我在以上所有答案中发现缺少关于如何高效地监听点击的解释,因为问题与onChange事件紧密耦合。另一件事是问题没有指定代码应该只使用Jquery,我认为添加纯JS解决方案应该是一个好主意。
这是我将要计数的复选框的HTML列表。我以稍微通用的方式处理问题,以便更容易地适用于不同的情况。我计划全局和每个部分计算复选框的数量。
<div class="wrapper">
<section class="list list-1">
<label for="id-11"><input type="checkbox" id="id-11"></label>
<label for="id-12"><input type="checkbox" id="id-12"></label>
<label for="id-13"><input type="checkbox" id="id-13"></label>
<label for="id-14"><input type="checkbox" id="id-14"></label>
<label for="id-15"><input type="checkbox" id="id-15"></label>
<label for="id-16"><input type="checkbox" id="id-16"></label>
<label for="id-17"><input type="checkbox" id="id-17"></label>
<label for="id-18"><input type="checkbox" id="id-18"></label>
<label for="id-19"><input type="checkbox" id="id-19"></label>
<label for="id-110"><input type="checkbox" id="id-110"></label>
<span class="list-score">Section 1: <span class="number">0</span></span>
</section>
<section class="list list-2">
<label for="id-21"><input type="checkbox" id="id-21"></label>
<label for="id-22"><input type="checkbox" id="id-22"></label>
<label for="id-23"><input type="checkbox" id="id-23"></label>
<label for="id-24"><input type="checkbox" id="id-24"></label>
<label for="id-25"><input type="checkbox" id="id-25"></label>
<label for="id-26"><input type="checkbox" id="id-26"></label>
<label for="id-27"><input type="checkbox" id="id-27"></label>
<label for="id-28"><input type="checkbox" id="id-28"></label>
<label for="id-29"><input type="checkbox" id="id-29"></label>
<label for="id-210"><input type="checkbox" id="id-210"></label>
<span class="list-score">Section 2: <span class="number">0</span></span>
</section>
<section class="list list-3">
<label for="id-31"><input type="checkbox" id="id-31"></label>
<label for="id-32"><input type="checkbox" id="id-32"></label>
<label for="id-33"><input type="checkbox" id="id-33"></label>
<label for="id-34"><input type="checkbox" id="id-34"></label>
<label for="id-35"><input type="checkbox" id="id-35"></label>
<label for="id-36"><input type="checkbox" id="id-36"></label>
<label for="id-37"><input type="checkbox" id="id-37"></label>
<label for="id-38"><input type="checkbox" id="id-38"></label>
<label for="id-39"><input type="checkbox" id="id-39"></label>
<label for="id-310"><input type="checkbox" id="id-310"></label>
<span class="list-score">Section 3: <span class="number">0</span></span>
</section>
<span class="total-score">Total: <span class="number">0</span></span>
</div>
以下是JS标记,它监听 .wrapper
div 中所有点击事件,并计算在 .wrapper
和每个 .list
部分上下文中选择的输入数量。
const total = document.querySelector('.total-score .number')
document.querySelector('.wrapper').addEventListener('change', function(event) {
const numberAll = this.querySelectorAll('input[type="checkbox"]:checked').length
total.innerHTML = numberAll
const list = event.target.closest('.list')
const numberList = list.querySelectorAll('input[type="checkbox"]:checked').length
list.querySelector('.list-score .number').innerHTML = numberList
})
这是JS fiddle中的实时示例:
https://jsfiddle.net/mkbctrlll/yak4oqj9/159/
在Vanilla JS中,你必须意识到为每个复选框应用
change
监听器会导致速度变慢。相反,你应该利用所谓的事件委托,将监听器应用于包装元素甚至整个文档。
在这里,你可以自己检查,在列表中每个输入监听change有多慢:
https://jsperf.com/change-listener-on-each-vs-event-delegation/1
较慢选项的代码(仅用于比较):
document.querySelector('.wrapper').addEventListener('change', function() {
const numberAll = this.querySelectorAll('input[type="checkbox"]:checked').length
total.innerHTML = numberAll
})
document.querySelectorAll('.list').forEach((list) => {
list.addEventListener('change', function() {
const numberAll = this.querySelectorAll('input[type="checkbox"]:checked').length
this.querySelector('.list-score .number').innerHTML = numberAll
})
})
我的jQuery解决方案:
$('.wrapper').change(function() {
const numberAll = $(this).find('input[type="checkbox"]:checked').length
total.innerHTML = numberAll
const $list = $(event.target).closest('.list')
const numberList = $list.find('input[type="checkbox"]:checked').length
$($list.find('.list-score .number')).html(numberList)
})
顺便说一句,我尝试了使用jQuery解决方案进行基准测试,但它的性能似乎是虚假的,所以我决定不使用它。