如何使用document.querySelectorAll()动态选择元素进行函数调用



我一直在研究这个小提琴:

https://jsfiddle.net/j1vrb7to/165/

小提琴里的代码是这样的:

HTML:

<div id="CalculationContainer">
<input type="numbers" class="form-control new-tuition" /> <br />
<input type="numbers" class="form-control new-tuition" /> <br />
<input type="numbers" class="form-control new-tuition" /><br /><br />
<input type="numbers" id="new-tuition-total" disabled="disabled" /><br /> <br />
<input type="numbers" class="form-control new-state" /> <br />
<input type="numbers" class="form-control new-state" /> <br />
<input type="numbers" class="form-control new-state" /><br /><br />
<input type="numbers" id="new-state-total" disabled="disabled" />
</div>

JavaScript:

const NewTuitionInputs = document.querySelectorAll("div#CalculationContainer > input.new-tuition");
const NewStateInputs = document.querySelectorAll("div#CalculationContainer > input.new-state");
NewTuitionInputs.forEach(function(input) {
input.onchange = function() {
var total = 0;
NewTuitionInputs.forEach(function(input) {
total += parseInt(input.value);
});
document.getElementById("new-tuition-total").value = total;
}
});
NewStateInputs.forEach(function(input) {
input.onchange = function() {
var total = 0;
NewStateInputs.forEach(function(input) {
total += parseInt(input.value);
});
document.getElementById("new-state-total").value = total;
}
});

当用户在文本框中输入值时,我想更新另一个字段的值以显示正在运行的总计。最终,我需要在我的表单上记录20多个运行总数。与其维护20多个函数,是否可以使用单个函数实时计算运行总数?下面是一些伪代码来演示我的想法:

var ThisInput = document.querySelectorAll("div#CalculationContainer > input.[INPUT_CLASS_PARAMETER_HERE]");
ThisInput.forEach(function(input) {
input.onchange = function() {
var total = 0;
ThisInput.forEach(function(input) {
total += parseInt(input.value);
});
document.getElementById("[DYNAMICALLY_CHOOSE_WHERE_TO_DISPLAY").value = total;
}
});

您有一个约定,即输入有一个类,然后总数有一个id,该id的类名加上-total。你可以利用这一点来制作一个通用函数:

function trackTotals(className){
var inputs = document.querySelectorAll(`div#CalculationContainer > input.${className}`);
inputs.forEach(input => {
input.addEventListener("change",()=>{
var total = [...inputs].reduce((acc,i) => acc + (parseInt(i.value,10) || 0),0);
document.getElementById(`${className}-total`).value = total;
})
})
}

使用方法为:

trackTotals("new-tuition");
trackTotals("new-state");
// whatever else that follows same conventions

下面是示例:

trackTotals("new-tuition");
trackTotals("new-state");
function trackTotals(className){
var inputs = document.querySelectorAll(`div#CalculationContainer > input.${className}`);
inputs.forEach(input => {
input.addEventListener("change",()=>{
var total = [...inputs].reduce((acc,i) => acc + (parseInt(i.value,10) || 0),0);
document.getElementById(`${className}-total`).value = total;
})
})
}
<div id="CalculationContainer">
<input type="numbers" class="form-control new-tuition"/> <br/>
<input type="numbers" class="form-control new-tuition"/> <br/>
<input type="numbers" class="form-control new-tuition"/><br/><br/>
<input type="numbers" id="new-tuition-total" disabled="disabled"/><br /><br />
<input type="numbers" class="form-control new-state"/> <br/>
<input type="numbers" class="form-control new-state"/> <br/>
<input type="numbers" class="form-control new-state"/><br/><br/>
<input type="numbers" id="new-state-total" disabled="disabled"/>
</div>

是的,您可以创建一个使用id:的函数

function doTotal(name) {
var ThisInput = document.querySelectorAll(`div#CalculationContainer > input.${name}`);

ThisInput.forEach(function(input) {
input.onchange = function() {
var total = 0;
ThisInput.forEach(function(input) {
total += parseInt(input.value);
});
document.getElementById(`${name}-total`).value = total;
}
});
}

请注意,我使用字符串模板来构建选择器字符串。

您可以使用事件委派方法:

const calcContainer = document.getElementById('CalculationContainer')
, sumElms = 
{ tuition: { sum: document.getElementById('new-tuition-total'), elms: [...document.querySelectorAll('input.new-tuition')] } 
, state:   { sum: document.getElementById('new-state-total'),   elms: [...document.querySelectorAll('input.new-state')]   }
}
;
calcContainer.oninput= ({target}) => 
{
if (!target.matches('.new-tuition, .new-state')) return
let sumElm = target.matches('.new-tuition') ? sumElms.tuition : sumElms.state
sumElm.sum.value = sumElm.elms.reduce((s,e)=>s+e.valueAsNumber,0)
}
#CalculationContainer input {
float: left;
clear:both;
width: 5em;
}
#CalculationContainer input:disabled {
margin-bottom: 1em;
font-weight: bold;
color:black;
}
<div id="CalculationContainer">
<input type="number" class="form-control new-tuition" value="0"> 
<input type="number" class="form-control new-tuition" value="0"> 
<input type="number" class="form-control new-tuition" value="0">
<input type="number" id="new-tuition-total" disabled="disabled" value="0">

<input type="number" class="form-control new-state" value="0"> 
<input type="number" class="form-control new-state"value="0"> 
<input type="number" class="form-control new-state"value="0">
<input type="number" id="new-state-total" disabled="disabled"value="0">
</div>

最新更新