DOM事件流(不适用于IE8及以下版本IE)
“DOM2级事件”规定的事件流包括三个阶段
当一个事件发生以后,它会在不同的DOM节点之间传播(propagation)。这种传播分成三个阶段:
第一阶段:从window对象传导到目标节点,称为“捕获阶段”(capture phase)。
第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
第三阶段:从目标节点传导回window对象,称为“冒泡阶段”(bubbling phase)。
绑定监听函数的方法
- HTML元素的on-属性
//js中定义fun方法。
<script type="text/javascript">
function fun(){
console.log(this)
}
</script>
<div id="test" onclick="fun()"></div>
//等同于 使用元素节点的setAttribute方法 设置相应的属性。
document.getElementById("test").setAttribute('onclick', 'fun()')
//等效于
document.getElementById("test").onclick=function onclick(event) {
fun()
}
- 属性值是可执行的代码,而不是监听函数,所以要执行函数,不要忘记加上一对圆括号。
- 事件触发后" "中的代码被执行。定义好的fun函数被调用。函数调用模式,非严格模式fun函数中this指向window。
- 使用这个方法指定的监听函数,只会在冒泡阶段触发。
- 若要访问event对象。必须要这样。在调用监听函数时间,一定要显示传入event对象
<div id="test" onclick="fun(event)"></div>
- Element节点的事件属性
Element节点有事件属性,同样可以指定监听函数。
div.onclick = function(){ console.log(this)};
- 事件触发后执行该元素节点的onclick方法。方法调用模式 , 函数中this指向该节点对象。
- 使用这个方法指定的监听函数,只会在冒泡阶段触发。
- 只能给元素节点和document节点指定监听函数,不能给文本节点指定监听函数。
- 使用addEventListener方法也可以在,定义一个特定事件的监听函数。
addEventListener是推荐的指定监听函数的方法。它有如下优点:
可以针对同一个事件,添加多个监听函数。
能够指定在哪个阶段(捕获阶段还是冒泡阶段)触发监听函数,默认为false(只在冒泡阶段被触发)。
除了DOM节点(所有DOM节点),还可以部署在window、XMLHttpRequest等对象上面,等于统一了整个JavaScript的监听函数接口。
- addEventListener 添加的方法只能用remoEventListener 移除
事件绑定时的this指向
以下写法的this对都指向Element节点:
// JavaScript代码
element.onclick = printelement.addEventListener('click', print, false)
element.onclick = function () {console.log(this.id);}
// HTML代码
<element onclick="console.log(this.id)">
以下写法的this,都指向全局对象。
// JavaScript代码
element.onclick = function (){ doSomething() };
element.setAttribute('onclick', 'doSomething()');
// HTML代码
<element onclick="doSomething()">
在监听函数中,currentTarget属性实际上等同于this对象。
IE8及以下版本,事件对象不作为参数传递,而是通过window对象的event属性读取,并且事件对象的target属性叫做srcElement属性。所以,以前获取事件信息,往往要写成下面这样。
var actualEvent = event || window.event;
var actualTarget = actualEvent.target || actualEvent.srcElement;
//...
}```
其他浏览器中事件对象会作为参传递,同时会将值赋给window.event
#####preventDefault():
preventDefault方法取消浏览器对当前事件的默认行为,比如点击链接 后,浏览器跳转到指定页面,或者按一下空格键,页面向下滚动一段距离。该方法生效的前提是,事件的cancelable属性为true,如果为false,则调用该方法没有任何效果。
#####event.stopPropagation():
stopPropagation方法阻止事件在DOM中继续传播,防止再触发定义在别的节点上的监听函数,但是不包括在当前节点上新定义的事件监听函数。
function stopEvent(e) {
e.stopPropagation();
}
el.addEventListener('click', stopEvent, false);
将上面函数指定为监听函数,会阻止事件进一步冒泡到el节点的父节点。
#####event.cancelBubble=true;
event.cancelBubble=true 阻止事件冒泡。不同于event.stopPropagation() 它阻止的只是冒泡阶段的事件传递,
关于阻止事件传递,一直有如下谬论:
>event.cancelBubble=true用于ie的阻止冒泡事件,
event.stopPropagation()用于firefox和chrome等其他浏览器。
ie9及以上版本IE,和其他浏览器(chrome Firefox safari opera Edge)中都可以用event.cancelBubble=true;取消事件冒泡。除此之外,这些浏览量器相对于低版本IE 还有了event.stopPropagation()方法 用于阻止事件在DOM中继续传播包括捕获和冒泡。
#####event.stopImmediatePropagation()
stopImmediatePropagation
方法阻止同一个事件的其他监听函数被调用。
如果同一个节点对于同一个事件指定了多个监听函数,这些函数会根据添加的顺序依次调用。只要其中有一个监听函数调用了stopImmediatePropagation方法,其他的监听函数就不会再执行了。
function l1(e){
e.stopImmediatePropagation();
}
function l2(e){
console.log('hello world');
}el.addEventListener('click', l1, false);
el.addEventListener('click', l2, false);
上面代码在el节点上,为click事件添加了两个监听函数l1和l2。由于l1调用了stopImmediatePropagation方法,所以l2不会被调用。
#####return false
可以同时取消事件冒泡和默认事件