为何jQuery click触发checkbox的click事件处理器执行3次?
为什么点击"All"复选框时,每个vehicle复选框的checkVehicle函数会被调用3次?
问题场景与初始代码
我尝试实现一个包含多个复选框的页面,点击“All”复选框时,其余复选框会同步切换选中状态,初始代码如下:
初始JavaScript代码
$(document).ready(function() { $("#all").click(function(event) { console.log("all"); $("input[name=vehicle]").each(function() { $(this).click(); }); }); }); function checkVehicle(event, id) { // console.log(event); console.log(id); }
初始HTML代码
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> <input type="checkbox" id="all" name="all" /> <label for="all">All</label> <input type="checkbox" id="car" name="vehicle" onclick="checkVehicle(event, 1)" /> <label>Car</label> <input type="checkbox" id="bike" name="vehicle" onclick="checkVehicle(event, 2)" /> <label>Bike</label> <input type="checkbox" id="truck" name="vehicle" onclick="checkVehicle(event, 3)" /> <label>Truck</label> <input type="checkbox" id="tank" name="vehicle" onclick="checkVehicle(event,4)" /> <label>Tank</label>
问题描述
点击“All”复选框时,每个name为vehicle的复选框对应的checkVehicle函数会被调用3次,我需要了解该现象的产生原因,而非解决方法。
原因分析
这个现象的核心是jQuery的click()方法与内联onclick事件的触发机制差异:
- jQuery的
$(element).click()方法并非单纯模拟原生点击行为,它会先触发jQuery事件队列中绑定的所有处理函数; - 随后,jQuery会调用原生的
.click()方法来模拟真实的用户点击,这会触发元素上的内联onclick事件; - 除此之外,jQuery的事件系统在处理过程中,会因为内部的事件分发逻辑,导致内联
onclick事件被额外触发一次;
三者叠加,最终导致每个checkVehicle函数被调用3次。
已找到的两种解决方式
方式一:触发DOM元素的原生click事件
直接调用DOM元素的原生click()方法,而非jQuery封装的方法,避免jQuery事件系统的额外触发:
$(document).ready(function() { $("#all").click(function(event) { console.log("all"); $("input[name=vehicle]").each(function() { $(this)[0].click(); }); }); }); function checkVehicle(event, id) { console.log(event); console.log(id); }
方式二:使用编程方式注册事件而非内联注册
放弃内联onclick属性,改用jQuery统一绑定事件,避免原生事件与jQuery事件系统的冲突:
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> <title>Document</title> </head> <body> <script src="index.js"></script> <input type="checkbox" id="all" name="all" /> <label for="all">All</label> <input type="checkbox" id="car" name="vehicle" /> <label>Car</label> <input type="checkbox" id="bike" name="vehicle" /> <label>Bike</label> <input type="checkbox" id="truck" name="vehicle" /> <label>Truck</label> <input type="checkbox" id="tank" name="vehicle" /> <label>Tank</label> </html>
index.js代码
$(document).ready(function() { $("#all").click(function(event) { console.log("all"); $("input[name=vehicle]").each(function() { $(this).click(); }); }); $("input[name=vehicle]").click(function() { console.log("personal"); }); });
内容的提问来源于stack exchange,提问作者nammae88
相关产品推荐
相关产品推荐

