今天同事(妹子)遇到一个 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) })
而后就正常了 页面2。spa
虽然妹子对我一阵赞许,但是我内心仍是隐隐不安,回来经过咨询大牛和看源码知道了这是什么缘由。code
先看看这个页面 页面3blog
查看源码咱们能够看到,页面3 和 页面1 几乎如出一辙,就是在 .a
和 .b
的事件委托顺序不同:队列
那为何 页面3 就能够正常呢?就是由于 Zepto 的事件委托和咱们想象中的事件委托是不同的。事件
Zepto
的事件委托是:rem
在代码解析的时候,全部document的全部
click
委托事件都依次放入一个队列里,click 的时候先看当前元素是否是.a
,符合就执行,而后查看是否是.b
,符合就执行。zepto
这样的话,就致使若是 .a
的事件在前面,会先执行 .a
事件,而后 class
更改为 b
,Zepto
再查看当前元素是否是 .b
,以此类推。
这就是 页面1 出现BUG的缘由,而 页面2 之因此也能解决这个问题是由于 class
变化实在延迟以后,click 事件当时没有检测到 .b
。
看看 Zepto 的事件部分是怎么写的。能够看到是用$this.each
循环绑定在 $this
上的事件。对应在咱们的例子,就是 document
上绑定的事件都被塞进一个队列中。
再看看 jQuery
的事件委托:
document上委托了2个 click 事件,click 后判断是否当前符合条件(选择符),而后把事件拿出来执行。
这是符合咱们通常的认知的,也是那个妹子那样写代码的缘由。你不妨把页面1的 Zepto
换成 jQuery
看看。
这是一个 Zepto
和 jQuery
不一样的地方,之后要注意了。
个人博客,欢迎订阅
微博粉丝太少,求粉