Html代码如下:
<div id="cover">
<input type="button" id="inside" value="submit_inside" />
</div>
<div id="cover_js">
<input type="button" id="inside_js" value="submit_inside_js" />
</div>
<input type="button" id="outside" value="submit_outside" />
jQuery代码如下:
$('#cover').mouseover(function () {
$('#inside').click(function () {
alert('multiple times');
});
});
$('#cover_js').mouseover(function () {
document.getElementById('inside_js').onclick = function () {
alert('just one time');
}
});
$('#outside').click(function () {
alert('just one time');
});
id 为 inside 的按钮的 click 事件被嵌套在 div 的鼠标事件内,而 id 为 outside 的按钮则未嵌套,分别对两个按钮进行多次点击后,inside 按钮绑定的 click 事件会进行累加,而 outside 按钮则仍旧只绑定一个 click 事件。id 为 inside_js 的按钮的 click 事件也被嵌套在 div 的鼠标事件内,但是我用 javascript 实现 click,此时点击多次后,只触发一个 alert。
解决上述问题可以用 unbind 对嵌套 event 进行解绑:
$('#cover').mouseover(function () {
$('#inside').unbind('click').click(function () {
alert('multiple times');
});
});
但是我想知道为什么 Jquery 嵌套 event 会对事件进行累加,从而导致触发多次呢?
1.所有的事件绑定(.click, .mouseover, .hover 等等)都是委托给更底层的 .on 方法的,通过查看其源码得知 .on 最终会调用 $.event.add 方法
2我没有细细去看 $.event 对象的全部内容,只是看到这一行的时候,我似乎有些明悟了。
jQuery 为每一个事件回调函数生成一个 guid,保证它们都是独一无二的(即使函数内容相同)
如果你继续往后看,会发现这些回调函数都被 push 到一个数组里保存,所以当时间触发的时候,它们也应该是一个个从数组里取出来再执行(或许是为了保证注册在同一事件下不同回调函数的执行顺序,但是像你这样内容一样的回调函数就不好判断了,所以如果你不得不多次绑定内容一样的回调,先解绑)。这就是为什么会产生你问题中效果的原因。
3.至于 jQuery 为什么要这样去设计我还没有去求证,我猜是为了更强大的事件管理能力,至于 bind after unbind 这样的副作用也许在 jQuery Team 看来是微不足道的牺牲吧。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。