问题描述
编辑:我已经用答案更新了代码。
1。我想根据跨度之一中可用的总数设置一些限制。例如10。因此增量不能超过10。#DONE
- 另一个问题是,我计划有多行,在保存之前,我想确保如果我们计算每行中的增量,它也不应超过10。如果它动态减少总数(跨度)会很好。
我使用ADD按钮动态添加行,如何添加实际上可与当前功能一起使用的新闻行?我的行只是克隆第一个,而增量功能已禁用。
document.addEventListener('DOMContentLoaded',async function() {
document.querySelector('#addlocationdest').addEventListener('click',add);
});
function add() {
var x = 1;
var container = document.getElementById('destination');
var detail = document.getElementById('row');
var clone = detail.cloneNode(true);
clone.id = "destination" + x;
x++;
container.appendChild(clone);
}
window.addEventListener("load",() => {
let elTotalQuantity = document.querySelector("#totalqty");
let totalQuantity = parseInt(elTotalQuantity.innerHTML);
function getSumOfRows() {
let sum = 0;
for (let input of document.querySelectorAll("form .row > input.quantity"))
sum += parseInt(input.value);
return sum;
}
for (let row of document.querySelectorAll("form .row")) {
let input = row.querySelector("input");
row.querySelector(".increment").addEventListener("click",() => {
if (getSumOfRows() >= totalQuantity) return;
input.value++;
elTotalQuantity.innerHTML = totalQuantity - getSumOfRows();
});
row.querySelector(".decrement").addEventListener("click",() => {
if (input.value <= 0) return;
input.value--;
elTotalQuantity.innerHTML = totalQuantity - getSumOfRows();
});
}
});
<div id="location" class="hide">
<div class="title">Transfer details</div><br>
<div class="line padded-s">Total Quantity: <span>10</span></div>
<br>
<form>
<label>New Total Quantity at this location: <span id="totalqty">10</span></label>
<br>
<div id="destination">
<div id="row" class="row">
<button type="button" class="decrement">-</button>
<input type="text" class="quantity" value="0" readonly/>
<button type="button" class="increment">+</button>
<a>Location: </a>
<input type="text" class="location" value="0" readonly/>
</div>
</div>
</form>
<label>Total being transfer: <p id="total-sum"></p></label>
<br>
<button type="button" id="addlocationdest">ADD</button>
<button type="button" id="removelocationdest">REMOVE</button>
</div>
解决方法
QuerySelector仅选择第一个出现的行,因此您并未真正向第二个“行”添加侦听器。您应该使用querySelectorAll,但要使用类来代替唯一的ID。
<input class="increment" type="button" value="+" />
-
现在您可以使用
document.querySelectorAll(".increment")
来获取数组中的所有元素。 -
您可以使用
parentElement
在DOM中遍历。通过知道单击了哪个按钮,可以遍历到表单元素,然后选择第一个子项-这是输入项。一种更动态的方法是使用querySelector
选择输入,以防将来HTML发生更改。无论如何,您可以根据按钮在DOM中的位置来知道要操纵哪个输入。 -
我添加了两个全局变量
totalSum
和maxSum
。从您的span元素(我为其分配了唯一的ID)中获取了 maxSum 。 totalSum 确保所有输入的总和不超过 maxSum 。 -
您有一些重复的代码,因此我将其重构为一个新方法:
changeValue
。
总的来说,我认为代码可以说明一切。
哦,这段代码没有考虑到用户可以更改输入中的值。我将留给您在每个文本输入上使用“ oninput”侦听器来解决。
var totalSum = 0; // 3
var maxSum = 0
var totalSumElement = null;
document.addEventListener('DOMContentLoaded',async function() {
totalSumElement = document.getElementById('total-sum');
maxSum = document.getElementById('max-sum').innerText;
var incrementElements = document.querySelectorAll('.increment'); // 1
var decrementElements = document.querySelectorAll('.decrement');
addListener('click',incrementElements,incrementValue);
addListener('click',decrementElements,decrementValue);
});
function addListener(type,elementArr,func) {
for (element of elementArr) {
element.addEventListener(type,func);
}
}
function withinRange(newValue) {
var maxReached = newValue > maxSum; // 3
var zeroReached = newValue < 0;
return !maxReached && !zeroReached;
}
function changeValue(event,change) { // 4
if (withinRange(totalSum + change)) {
let parent = event.currentTarget.parentElement; // 2
let input = parent.children[0];
let value = parseInt(input.value) || 0;
if (withinRange(value + change)) {
input.value = value + change;
totalSum = totalSum + change;
}
}
totalSumElement.textContent = `Total: ${totalSum}`;
}
function incrementValue(event) {
changeValue(event,1);
}
function decrementValue(event) {
changeValue(event,-1);
}
#totalqty {
padding-bottom: 1rem;
}
<div id="totalqty" class="line padded-s">Total Quantity: <span id="max-sum">10</span></div>
<form>
<input type="text" value="0" />
<input class="increment" type="button" value="+" />
<input class="decrement" type="button" value="-" />
</form>
<form>
<input type="text" value="0" />
<input class="increment" type="button" value="+" />
<input class="decrement" type="button" value="-" />
</form>
<p id="total-sum"></p>
,
序言
只要脚本执行开始时固定总数量,就可以使用。否则,最好将实际允许的总量保存为属性,并使用MutationObserver进行观察。这样您就可以更新最高总数量属性更改时,代码中的值动态变化。您可以通过将custom attributes命名为“ data- *”来定义,其中“ *”是自定义名称。
解决问题的方法
您正在多个元素上使用相同的ID。您的意思是类,因此将id="increment"
更改为class="increment"
,将decrement
更改为相同内容。
由于我们不想在按钮上输入任何内容,而是在按钮上添加侦听器,所以我说最好使用<button>
。在表单中,按钮充当type="submit"
,这是我们不想要的,因此我们需要将其更改为type="button"
。
由于行和总数实际上属于同一行,因此将它们放到一个 <form>
元素中是比较明智的。但是,您仍然可以使用<div>
将按钮和输入分组为一行。
现在有关行值的增/减和总数:
- 将允许的总量保存在变量中
- 将事件监听器添加到相应的按钮
- 如果操作有效,请更改行的值
- 将总数更新为
totalQuantity - getSumOfRows()
要动态添加新行,我们创建并设置了这样的元素,并将其附加到表单中。请参阅下面的appendNewRow()
函数。
边注
我已将readonly
属性添加到输入字段,以便您无法通过键盘输入数字。
window.addEventListener("load",() => {
let elTotalQuantity = document.querySelector("#totalqty");
let totalQuantity = parseInt(elTotalQuantity.innerHTML);
function getSumOfRows() {
let sum = 0;
for (let input of document.querySelectorAll("form .row > input.quantity"))
sum += parseInt(input.value);
return sum;
}
function updateTotalQuantity() {
elTotalQuantity.innerHTML = totalQuantity - getSumOfRows();
}
function appendNewRow() {
let row = document.createElement("div");
row.classList.add("row");
let child;
// input.quantity
let input = document.createElement("input");
input.classList.add("quantity");
input.value = "0";
input.setAttribute("readonly","");
input.setAttribute("type","text");
row.append(input);
// button.increment
child = document.createElement("button");
child.classList.add("increment");
child.innerHTML = "+";
child.setAttribute("type","button");
child.addEventListener("click",() => {
if (getSumOfRows() >= totalQuantity) return;
input.value++;
updateTotalQuantity();
});
row.append(child);
// button.increment
child = document.createElement("button");
child.classList.add("decrement");
child.innerHTML = "-";
child.setAttribute("type",() => {
if (input.value <= 0) return;
input.value--;
updateTotalQuantity();
});
row.append(child);
// button.remove-row
child = document.createElement("button");
child.classList.add("remove-row");
child.innerHTML = "Remove";
child.setAttribute("type",() => {
row.remove();
updateTotalQuantity();
});
row.append(child);
document.querySelector("form .rows").append(row);
}
document.querySelector("form .add-row").addEventListener("click",() => appendNewRow());
appendNewRow();
});
<form>
<label>Total Quantity: <span id="totalqty">10</span></label>
<br>
<div class="rows">
</div>
<button type="button" class="add-row">Add new row</button>
</form>