Zepto事件委托的小坑

问题

今天同事(妹子)遇到一个 Zepto 的事件委托的问题来问我,我当时也懵了,后来解决了。问题仍是比较坑的,拿出来分享一下。先看看是什么问题:git

页面1github

本身解决

为何?!为何事件委托在 .a 上但是却也触发了 .b 上的委托。看着妹子求知的眼神,我胸中一阵气短。猜测着是 .a 委托事件最后换了 class,DOM马上更改了,就在 .a 事件后触发了 .b。因此我马上让她这样改一下就能够延缓DOM更改:this

$doc.on('click','.a',function(){
    alert('a事件')
    var $this = $(this) ;
    setTimeout(function(){
        $this.removeClass('a')
        .addClass('b')    
    },30)
})

而后就正常了 页面2spa

刨根问底

虽然妹子对我一阵赞许,但是我内心仍是隐隐不安,回来经过咨询大牛和看源码知道了这是什么缘由。code

先看看这个页面 页面3blog

查看源码咱们能够看到,页面3页面1 几乎如出一辙,就是在 .a.b 的事件委托顺序不同:队列

89602268.jpg

29574817.jpg

那为何 页面3 就能够正常呢?就是由于 Zepto 的事件委托和咱们想象中的事件委托是不同的。事件

Zepto 的事件委托是:rem

在代码解析的时候,全部document的全部 click 委托事件都依次放入一个队列里,click 的时候先看当前元素是否是.a,符合就执行,而后查看是否是.b,符合就执行。zepto

这样的话,就致使若是 .a 的事件在前面,会先执行 .a 事件,而后 class 更改为 bZepto再查看当前元素是否是 .b,以此类推。

这就是 页面1 出现BUG的缘由,而 页面2 之因此也能解决这个问题是由于 class 变化实在延迟以后,click 事件当时没有检测到 .b

看看 Zepto 的事件部分是怎么写的。能够看到是用$this.each 循环绑定在 $this 上的事件。对应在咱们的例子,就是 document 上绑定的事件都被塞进一个队列中。

再看看 jQuery 的事件委托:

document上委托了2个 click 事件,click 后判断是否当前符合条件(选择符),而后把事件拿出来执行。

这是符合咱们通常的认知的,也是那个妹子那样写代码的缘由。你不妨把页面1的 Zepto 换成 jQuery 看看。

这是一个 ZeptojQuery 不一样的地方,之后要注意了。

个人博客,欢迎订阅

微博粉丝太少,求粉

相关文章
相关标签/搜索