js事件流

ps: 事件流在js的执行中占据一个很重要的角色,今天这里汇总一下,以便某日脑子被轰炸了再查看之用

1.事件流

        事件流:从页面中接收事件的顺序。也就是说当一个事件产生时,这个事件的传播过程,就是事件流。
1.1 IE的事件流 [ 很恶心微软这b的破浏览器 ]


IE中的事件流叫事件冒泡,事件冒泡:事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点(文档)。对于html来说,就是当一个元素产生了一个事件,它会把这个事件传递给它的父元素,父元素接收到了之后,还要继续传递给它的上一级元素,就这样一直传播到document对象(亲测现在的浏览器到window对象,只有IE8及下不这样);

再多说一句,现在的浏览器默认是采用的是事件冒泡(重点,圈起来;在DOM0级方法绑定事件只能是事件冒泡,不能设置;在DOM2级你可以设置是用事件冒泡还是事件捕获。 有图有真相,发图不留种,菊花万人捅

js事件流 - 眷恋天空的驴 - javscript

 (ps:很形象的事件冒泡原理事件图)

2 事件捕获

事件捕获 是网景(Netscape)提出来的,事件捕获是不太具体的元素应该更早接受到事件,而最具体的节点应该最后接收到事件。他们的用意是在事件到达目标之前就捕获它;也就是跟冒泡的过程正好相反,以html的click事件为例,document对象(DOM级规范要求从document开始传播,但是现在的浏览器是从window对象开始的)最先接收到click事件的然后事件沿着DOM树依次向下传播,一直传播到事件的实际目标;我测试了一下(我用的都是最新的浏览器),chrome,opera,firefox,IE11到IE9都支持事件捕获

ps: 事件捕获很事件冒泡完全是一个逆过程。

3 DOM事件流

DOM2 级中规定了事件流要包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。这是W3C采用了他们两家的事件监听机制。(说点题外话,w3c中的很多标准就是这样,浏览器厂商有很多自己的私有解决问题方式,好用的就被W3c采纳了)DOM2级还规定,实际发生事件的元素在捕获阶段不能接收到事件。我们就以上面的事件冒泡时的代码说明这个过程:按照标准是这样的,当一个元素产生了事件,事件是从document到html再到body再到DIV爷爷再到DIV爸爸,这时候捕获阶段就应该停止了,再进入下一个阶段“处于目标阶段”,然后是从DIV爸爸到DIV爷爷再到body再到html再到document,这就是事件冒泡阶段;实际上我们把处于目标阶段即第二阶段看作是冒泡阶段的一部分,即冒泡的开始;

js事件流 - 眷恋天空的驴 - javscript


友善提醒由于老版本浏览器不支持,很少有人使用事件捕获。建议使用事件冒泡


4.事件冒泡最常见的应用:--事件代理(事件委托)

传统的事件处理中,需要为每个元素添加事件处理器。js事件代理则是一种简单有效的技巧,通过它可以把事件处理器添加到一个父级元素上,从而避免把事件处理器添加到多个子级元素上。

事件代理的原理用到的就是事件冒泡和目标元素,把事件处理器添加到父元素,等待子元素事件冒泡,并且父元素能够通过target(IE为srcElement)判断是哪个子元素,从而做相应处理。关于target更多内容请参考javaScript事件(四)event的公共成员(属性和方法)

    
    
<body>
< ul id ="color-list" >
< li >red </ li >
< li >orange </ li >
< li >yellow </ li >
< li >green </ li >
< li >blue </ li >
< li >indigo </ li >
< li >purple </ li >
</ ul >
<script>
(function(){
var colorList=document.getElementById("color-list");
colorList.addEventListener('click',showColor,false);
function showColor(e)
{
e=e||window.event;
var targetElement=e.target || e.srcElement; //
要是这个东西都看不懂,我只能呵呵让你跳出这篇文章。好吧。

if(targetElement.nodeName.toLowerCase()==="li"){
alert(targetElement.innerHTML);
}
}
})();
</script>
</body>


最后在脑补一下DOM0级事件处理跟DOM1级处理,免得有人看不懂这个是什么JB玩意。

DOM0级事件处理程序

这种方法简单而且跨浏览器,但是只能为一个元素添加一个事件处理函数。因为这种方法为元素添加多个事件处理函数,则后面的会覆盖前面的。

<input id="myBtn" type="button" value="click me!"/>

<script>

    var myBtn=document.getElementById("myBtn");

    myBtn.onclick=function(){

        alert("clicked!");

    }

</script>

// 删除事件或者清理事件的:

    myBtn.onclick=null;

DOM2级事件处理程序

DOM2级事件处理程序可以为一个元素添加多个事件处理程序。其定义了两个方法用于添加和删除事件处理程序:addEventListener()和removeEventListener()。【ps: 完美封装请查看 下面有个事件处理

这两个方法都需要3个参数:事件名,事件处理函数,布尔值。

这个布尔值为true,在捕获阶段处理事件,为false,在冒泡阶段处理事件,默认为false

添加事件处理程序:现在为按钮添加两个事件处理函数,一个弹出“hello”,一个弹出“world”。



<input id="myBtn" type="button" value="click me!"/>
<script>
    var myBtn=document.getElementById("myBtn");
    myBtn.addEventListener("click",function(){
        alert("hello");
    },false);
    myBtn.addEventListener("click",function(){
        alert("world");
    },false);
</script>

删除事件处理程序:通过addEventListener添加的事件处理程序必须通过removeEventListener删除,且参数一致。

note:通过addEventListener添加的匿名函数将无法删除。下面这段代码将不起作用!ps: 完美封装请查看 下面有个事件处理 

1、实际应用场景

IE8及以下浏览器不支持addEventListener,在实际开发中如果要兼容到IE8及以下浏览器。如果用原生的绑定事件,需要做兼容处理,可利用jquery的bind代替。

2、IE8事件绑定

IE8及以下版本浏览器实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。

这两个方法都需要两个参数:事件处理程序名称事件处理程序函数

note:

IE11只支持addEventListener

IE9,IE10对attachEvent和addEventListener都支持

TE8及以下版本只支持attachEvent

可以拿下面代码在IE各个版本浏览器中进行测试。

note:IE事件处理程序中还有一个地方需要注意:作用域。可以查看完美封装中是做了这一步的处理的。

使用attachEvent()方法,事件处理程序会在全局作用域中运行,因此this等于window。

而dom2或dom0级的方法作用域都是在元素内部,this值为目标元素。

下面例子会弹出true。

<input id="myBtn" type="button" value="click me!"/>
<script>
var myBtn=document.getElementById("myBtn");
myBtn.attachEvent(
"onclick",function(){
alert(
this===window);
});
</script>

总结: 其实很简单,插入一首杨哥的音乐作为结束吧,FUCK!! 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值