序言:搜索基于 Diego 关于动态字段 JS 创建的回答 和 Anthony Awuley 关于创建字段的 MutationObserver 的回答
我花了很多时间(搜索和)找到适合我需要的解决方案,但结果 - 即使它是功能性的 - 对我来说似乎有点沉重。
我想根据传输给它的某些信息创建一个动态表单,以便创建将由网络服务发送给承运人的货物。这些信息包括创建包裹时不得超过的重量限制。这些包的数量由用户在专用字段中指示,并且根据需要动态创建尽可能多的字段。
我之前尝试监听“权重”字段的变化,并在输入时计算权重的总和,但考虑到页面加载时,字段尚未创建,因此没有什么可听的。
然后是2个问题:
为了简化演示,我减少了创建的字段数。
HTML
<div id="total-order-weight">20</div>
<div id="over-weight-alert" style="display:none; color:red;">OVER WEIGHT</div>
<form action="#" id="parcel-form" method="post">
<div class="multiparcel">
<input type="number" class="qty" min="0">
<div class="parcels"></div>
</div>
</form>
</div>
JS 字段创建
<script>
overWeightAlert = document.querySelector('#over-weight-alert');
totalOrderWeight = parseInt(document.querySelector('#total-order-weight').innerHTML);
parcelForm = document.querySelector('#parcel-form');
//add input e listener to qty input
qtyEl = document.querySelector('.qty')
qtyEl.addEventListener('input', (e) => {
const qtyEl = e.target;
const qty = e.target.value;
clearweights(qtyEl);
addweights(qtyEl, qty);
});
//removes the weights in the given multiparcel
function clearweights(from) {
const target = from.closest('.multiparcel').querySelector('.parcels');
target.innerHTML = '';
}
//adds a number of weights in the given multiparcel
function addweights(from, n) {
const target = from.closest('.multiparcel').querySelector('.parcels');
for (let i = 0; i < n; i++) {
group = createGroup()
const weight = createweights();
const insurance = createInsurance();
group.append(weight);
group.append(insurance);
target.append(group);
}
}
function createGroup() {
const group = document.createElement('div');
group.classList.add('input-group', 'my-2');
return group;
}
function createweights() {
const label = document.createElement("Label");
label.htmlFor = "weight";
label.innerHTML = "Poids";
label.classList.add('form-label');
const input = document.createElement('input');
input.name = 'parcel-weight';
input.type = "number";
input.classList.add('form-control', 'me-4');
const weight = document.createElement('div');
weight.classList.add('weight');
weight.append(label);
weight.append(input);
return weight;
}
function createInsurance() {
const label = document.createElement("Label");
label.htmlFor = "insurance";
label.innerHTML = "Assurance";
label.classList.add('form-label');
const input = document.createElement('input');
input.classList.add('insurance-name', 'form-control', 'ms-4');
input.value = 0;
const insurance = document.createElement('div');
insurance.classList.add('insurance');
insurance.append(label);
insurance.append(input);
return insurance;
}
</script>
JS MUTATIONOBSERVER
<script>
const targetNode = document.getElementById("parcel-form");
// Options for the observer (which mutations to observe)
const config = { childList: true, subtree: true };
// Callback function to execute when mutations are observed
const callback = (mutationList, observer) => {
for (const mutation of mutationList) {
if (mutation.type === "childList") {
overWeightAlert.style.display = 'none';
weights = parcelForm.querySelectorAll('input[name="parcel-weight"]');
weights.forEach(weight => {
weight.addEventListener('keyup', (event) => {
var check = checkWeight();
if (check > totalOrderWeight) {
overWeightAlert.style.display = 'block';
} else {
overWeightAlert.style.display = 'none';
}
});
})
}
}
};
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
// // Start observing the target node for configured mutations
observer.observe(targetNode, config)
// ---------------------------- END DOM CHANGES DETECTION
function checkWeight() {
weights = parcelForm.querySelectorAll('input[name="parcel-weight"]');
var totalWeight = 0;
for (var i = 0; i < weights.length; i++) {
qty = weights[i].value;
if (qty) {
totalWeight += parseInt(qty);
}
}
return totalWeight;
}
</script>