当我们打开网页时,我们会触发各种各样的事件,比如加载页面完成就会触发onload
事件,点击某个元素就会触发其click
事件。那么我们应该如何为我们的DOM元素绑定事件?一般操作事件会有三种方式:
HTML事件处理程序 - 直接HTML内联属性(不建议这么做)
|
|
DOM 0级事件处理程序 - DOM属性的绑定
|
|
DOM 2级事件处理程序 - 使用标准的事件监听函数
为DOM元素添加事件:
element.addEventListener(event, function, useCapture)
为DOM元素移出事件:
element.removeEventListener(event, function, useCapture)
event
为事件名称,function
为事件触发后的回调函数,useCapture
为一个用户选项
useCapture
指定事件是在捕获阶段执行还是冒泡阶段执行,默认为false在冒泡阶段执行,true则为事件句柄在捕获阶段执行
这里就不得不提DOM的事件流,”DOM2级事件”规定事件流包括3个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段
当我们在DOM树上的某个节点发生操作时,就会有一个事件发出。这个事件从window发出,通过DOM树到达目标节点,也就是发生操作的节点。捕获过程中,凡是经过节点上有该事件是定义在捕获阶段执行的,就会被触发。
冒泡阶段与捕获阶段原理基本相同,到达目的节点,目标阶段结束后,会依据冒泡阶段的DOM树路径返回,触发经过节点对于该事件在冒泡阶段的执行。
利用事件冒泡的机制,我们能够减少对于元素的大量绑定,只需统一绑定在父元素上即可,也称为事件委托,有利于页面整体运行的性能。同时我们需要进行一些DOM节点的插入与删除,仅仅绑定在一个节点上往往会由于插入删除而失效,事件冒泡也能很好地解决这个问题。
当然你如果只想触发特定元素上的绑定事件,可以在回调函数中使用event.stopPropagation()
来阻止事件的冒泡,注意:该函数并非是来阻止冒泡阶段发生的,而是执行后终止该事件继续传播,无论其处于什么阶段
在触发DOM上的某个事件时,会产生一个事件对象event,之前已经略有提及。其包含了许多与事件相关的属性与方法,比较常见的有:
event.type
被触发的事件类型,比如’click’, ‘mouseover’;
event.target
事件的目标,注意与event.currentTarget
的区别,currentTarget为当前正在处理事件的元素,可能为冒泡或是捕获阶段,target目标元素的父元素;
event.clientX/Y
是在事件发生时,鼠标指针与可视区域网页顶部和左部的距离。event.pageX/Y
与其稍稍不同,是与整个网页的顶部和左部距离。在没有滚动条的情况下两者的值是一致的,有滚动条的情况下,pageX >= clientX,pageY >= clientY;
event.preventDefault()
取消事件的默认行为,比如a标签的超链接;
在javascript的事件处理中,我们有时还需要考虑到IE的兼容性。比如,上文提及的DOM方法中addEventListener
对应IE的attachEvent
,removeEventListener
对应IE的detachEvent
,在此方法下,事件处理程序会在全局作用域中运行。
|
|
IE中的事件对象与DOM的也略有不同,我们也建议在书写时考虑浏览器的兼容性
|
|
上周做了拉钩网首页一个小效果的demo,其中需要根据鼠标移入移出元素来实现js效果,这里我留意到了鼠标移动事件。
目前存在两组鼠标移动事件,mouseover
与mouseout
均会冒泡,并且不论鼠标指针穿过被选元素或其子元素,都会触发事件,而且无法阻止其冒泡;mouseenter
与mouseleave
则不冒泡,只有在鼠标指针穿过被选元素时,才会触发事件。一般我们为了防止事件反复触发,以及动画的抖动,选择mouseenter/mouseleave
事件。