jQuery 嵌套 event 会触发多次的原因?

 最近,在公司做项目时,发现在click中嵌套click事件,会发生多次调用的问题,经过查询相关资料 ,特整理。文中有参考https://segmentfault.com/q/1010000000458432等。

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" />


JS代码:

$('#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');
});


随后,本人又进行了原生js中addEventListener,发现不论是jQuery的事件(click,mouseover等),还是原生的addEventListener,或者原生的onclick,只要放在外层函数,而内层函数是jQuery的事件绑定,或者原生addEventListener,都会有事件累积的效应。但是如果内层函数是onlick,则不会有事件累积发生。 

以上是发现的规律,解决方法有:

1.unblind方法

$('#cover').mouseover(function () {
  $('#inside').unbind('click').click(function () {
    alert('multiple times');
  });    
});


2.尽可能不要使用事件嵌套,把事件拆出来

3.通过定义一个相反的外层事件解绑内嵌的事件

var foo = function () {
    alert('multiple times');
};

$('#cover').mouseover(function () {
    $('#inside').bind('click', foo);        
});

$('#cover').mouseout(function () {
    $('#inside').unbind('click', foo);
});


4.通过定义一个 flag 变量来阻止内嵌事件的累加

var flag = true;

var foo = function () {
    alert('multiple times');
};

$('#cover').mouseover(function () {
    if (flag) {
        $('#inside').bind('click', foo);
        flag = false;
    }
});


产生这种现象的原因(照搬过来了):

  1. 所有的事件绑定(.click.mouseover.hover 等等)都是委托给更底层的 .on 方法的,通过查看其源码得知 .on 最终会调用 $.event.add 方法

  2. 我没有细细去看 $.event 对象的全部内容,只是看到这一行的时候,我似乎有些明悟了。

    1. jQuery 为每一个事件回调函数生成一个 guid,保证它们都是独一无二的(即使函数内容相同)

    2. 如果你继续往后看,会发现这些回调函数都被 push 到一个数组里保存,所以当时间触发的时候,它们也应该是一个个从数组里取出来再执行(或许是为了保证注册在同一事件下不同回调函数的执行顺序,但是像你这样内容一样的回调函数就不好判断了,所以如果你不得不多次绑定内容一样的回调,先解绑)。这就是为什么会产生你问题中效果的原因。

  3. 至于 jQuery 为什么要这样去设计我还没有去求证,我猜是为了更强大的事件管理能力,至于 bind after unbind 这样的副作用也许在 jQuery Team 看来是微不足道的牺牲吧。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值