preventDefault vs. stopPropagation vs. stopImmediatePropagation

发布:elantion 日期:2019-08-12 阅读:56 评论:0

在添加DOM元素事件时,很常发生事件冲突,例如想住已经添加了click事件的元素上再添加个touchStart事件,应该怎么避免触发click呢?我们来看看常用的几个方法,看完之后,你就会有答案了。

preventDefault

如果绑定的元素存在别的事件,那么使用Event.preventDefault()方法就会终止接下来的所有事件,例如在touchMove事件上使用该方法,那么默认的scroll就会不触发,也就是不能滑动了。但这个方法是有限制的,它只能终止事件对象Event里属性 cancelable 不为真的事件,例如通过EventTarget.dispatchEvent()方法创建的,并且cancelabletrue时,就不能通过event.preventDefault()来终止该事件了。还有个限制条件,在事件链上,后触发的事件没法停止前触发的事件,例如click事件就没办法停止touchStart事件,因为tocuhStart事件比click更早触发。

stopPropagation

还记得之前我翻译的文章《DOM事件传递》https://www.lazycoffee.com/articles/view?id=5b4ea01b5130605c21201f2f 吗?里面有说到事件有捕抓和冒泡模式,而event.stopPropagation()就是在冒泡模式时,停止继续冒泡。例如:在父元素和子元素注册了相同事件时,该方法就可以只触发子元素的事件,而不会同时触发父元素事件。

stopImmediatePropagation

如果一个元素里同时注册了两个相同的事件,在触发其中一个时,为了避免同时触发别的事件,这时候就可以使用 event.stopImmediatePropagation() 了,它可以防止该元素其它事件的触发。注意限制条件,相同的事件类弄和相同的元素。使用的场景比较少,所以很少出现在我们的视野中。

总结

看完上面这几个方法,大家应该知道答案是preventDefault了吧?因为touchStart比click更早触发,而且是同个元素,所以用event.preventDefault()就可以停止事件链的其它默认的行为:touchStart -> touchEnd-> click,同理,touchEnd也是可以停止触发的哦,大家看懂了吗?
题外话,jQuery在事件函数里使用return false,实际是执行了event.preventDefault()event.stopPropagation()