我正在处理大量输入(100-1000)。我需要为每个人创建一个函数,如下所示:
const range1 = document.getElementById("a1");
const range2 = document.getElementById("a2");
//label1 shows a value from range1 + 3
range1.oninput = function() {
document.getElementById("label1").innerHTML = parseInt(this.value) + 3;
};
range2.oninput = function() {
document.getElementById("label2").innerHTML = parseInt(this.value) + 3;
};
我可以通过某种方式使它自动化吗?
答案 0 :(得分:1)
最好的方法是仅将一个侦听器分配给其共同的父母
document.getElementById(commonParentId).oninput = e =>
document.getElementById("label" + e.target.id.substring(1))
.innerHTML = parseInt(e.target.value) + 3
答案 1 :(得分:1)
当可以在未知或大量元素上完成相同任务时,事件委托是最好的选择,恕我直言。
什么是事件委托?
简而言之,您可以让一个共同的祖先处理原本分配给各个元素的任务。例如您无需将点击侦听器绑定到 n 元素,而是将其分配给一个共同的祖先。 (Read more。)为什么更好?
如果您不小心添加过多的事件侦听器,则 最终会降低应用的感知性能。您的用户会觉得呆滞。
这是约翰·雷西格(John Resig)所说的:
事件委托是一种监视大量元素事件的有效方法。
来源:https://johnresig.com/apps/workshop/adv-talk/index2.html#3
演示时间!
每2秒钟,我会将以下元素添加到DOM中:(生成X)
<div>
<input type="range" id="inpX"/>
<label for="inpX"><!-- SOME DYNAMIC VALUE --></label>
</div>
用户调整范围后,<label>
将立即更新。
全部带有一个事件监听器!
// set el content to given txt
const write = (el, txt) => el.innerText = txt;
// return the <label> for given id
const label = id => document.querySelector(`label[for="${id}"]`);
// one global event listener - event delegation FTW!
document.body.addEventListener('input', ev => {
const {id, value} = ev.target;
write(label(id), parseInt(value) + 3);
});
<script>
// This code is only for the demo
// It is not part of the answer
function append(n) {
const div = document.createElement('div');
const id = `inp${n}`;
div.innerHTML = `
<input type="range" id="${id}"/>
<label for="${id}"></label>
`;
document.body.appendChild(div);
}
function start() {
let n = Date.now();
append(n++);
start.timer = setInterval(() => append(n++), 2000);
}
function stop() {
clearInterval(start.timer);
}
</script>
<button onclick="start()">START</button>
<button onclick="stop()">STOP</button>
<hr>
答案 2 :(得分:0)
这是一个简单的演示:
const ranges = document.querySelectorAll("input[type=range]");
for (i = 0; i < ranges.length; ++i) { //for each input[type=range]
ranges[i].oninput = oninput; //set on change
oninput.call(ranges[i]); //set on load
}
function oninput() {
this.parentElement.querySelector("span").innerHTML = parseInt(this.value) + 3;
};
<label><input type=range /><span></span><label><br />
<label><input type=range /><span></span><label>
答案 3 :(得分:0)
您可以轻松地使用数组和循环:
let inputNum = 100;
let range = [];
for(let i = 1; i <= inputNum; i++) {
range[i] = document.getElementById(`a${i}`);
range[i].oninput = function() {
document.getElementById(`label${i}`).innerHTML = parseInt(this.value) + 3;
};
}
答案 4 :(得分:-1)
有很多框架可以使这些事情自动化。 用普通的html / js可以做什么:
<label for='a1'></label>
<label for='a2'></label>
<input id='a1' class='range-input-output-to-label'/>
<input id='a2' class='range-input-output-to-label'/>
<script>
const inputs = document.getElementsByClassName('number-input-output-to-label')
const outputNumberToLabel = (e) => {
const labels = e.target.labels
for (let i = 0; i < labels.length; i++)
labels[i].innerText = parseInt(e.target.value) || 0
}
for (let i = 0; i < inputs.length; i++)
inputs[i].oninput = outputNumberToLabel
</script>
在这里,我将香草用于循环,因为本机元素列表不是数组,并且不支持forEach。
我建议再次修改ID以查找标签,因为稍后进行调试可能很棘手。