你不知道的JavaScript--Item35 事件流与事件处理_事件流头部

alert(‘first’);
}
function fn2(){
alert(‘second’);
}
window.οnlοad=function(){
document.getElementById(‘div1’).οnclick=fn1;
document.getElementById(‘div1’).οnclick=fn2;
};

test

```

如果我们想为一个对象的某个事件指定多个事件处理,可以考虑使用事件监听

事件监听语法:

IE:
    attachEvent(type,callback)
        type:事件名  如:onclick、onsubmit、onchange等
        callback:事件处理程序

基于W3C模型:
    addEventListener(type,callback,capture)
        Type:事件名 ,没有“on”前缀  如:click、submit、change
        Callback:事件处理程序
        Capture:事件模型 (可选参数)   (冒泡模型、捕捉模型) true:捕捉模型  
                                                         false:冒泡模型 (默认值)

代码示例:

<body>
    <script>
 function fn1(){
 alert('first');
 }
 function fn2(){
 alert('second');
 }
 window.onload=function(){
 document.getElementById('div1').attachEvent('onclick',fn1);
 document.getElementById('div1').attachEvent('onclick',fn2);
 };
 </script>
    <div id='div1'>test</div>
 </body>

W3c:

<body>
    <script>
 function fn1(){
 alert('first');
 }
 function fn2(){
 alert('second');
 }
 window.onload=function(){
 document.getElementById('div1').addEventListener('click',fn1);
 document.getElementById('div1').addEventListener('click',fn2);
 };
 </script>
    <div id='div1'>test</div>
 </body>

总结:

IE和W3C事件监听的不同:

  1. 监听方法不同:IE attachEvent 、W3C addEventListener
  2. 监听参数不同:IE 没有模型参数、W3C有模型参数 ,默认flase,为事件冒泡。
  3. 触发顺序:IE 8及以下的浏览器触发时是先绑定、后触发 W3C浏览器是先绑定、先触发
  4. 事件名称不同:IE事件需要”on”前缀,W3C不需要’on’前缀

解决事件监听的兼容性问题:

这里写图片描述

2. 事件流

2.1 事件模型

事件模型(事件的触发顺序)分为两种:Body嵌套div1,div1嵌套div2,div2嵌套div3
1)冒泡模型
2)捕捉模型

这里写图片描述

目前,IE只支持冒泡模型

2.2 事件冒泡

事件冒泡是指事件响应时会上水冒一样上升至最顶级元素。

简单点说。冒泡就是从下往上,像鱼吐泡,泡泡是从下往上升的,也就是DOM元素被触法事件时(此时的dom元素为目标元素),目标元素事件执行后,它的祖先元素所绑定的事件会向上顺序执行。

如下代码,有四个div嵌套元素,均绑定了click事件,addEventListener函数的第三个参数设置为false说明不为捕获事件,即为冒泡事件。该代码执行结果如下:

<div id="one" style="height: 100px;background: black;">
  <div id="two" style="height: 50px;background: blue;">
    <div id="three" style="height: 30px;background: green;">
      <div id="four" style="height: 10px;background: red;">
      </div>
    </div>
  </div>
</div>
<script type='text/javascript'>
 var one=document.getElementById('one');
 var two=document.getElementById('two');
 var three=document.getElementById('three');
 var four=document.getElementById('four');
 one.addEventListener('click',function(){
 alert('one');
 },false);
 two.addEventListener('click',function(){
 alert('two');
 },false);
 three.addEventListener('click',function(){
 alert('three');
 },false);
 four.addEventListener('click',function(){
 alert('four');
 },false);
</script>

点击one元素,输出one;

点击two元素,输出two one;

点击three元素,输出 three two one;

点击four元素,输出 four three two one;

这里写图片描述

2.3事件捕获

而冒泡则相反。当触发目标元素时,会从目标元素的最顶层的祖先元素事件往下执行到目标元素为止。

将上面的代码第三个参数均改为true,则执行结果如下:

  • 点击one,输出one;
  • 点击two,输出one two;
  • 点击three,输出one two three;
  • 点击four,输出one two three four;

很明显执行顺序是不同的。

以上便是冒泡和捕获的基本理解。

2.4 w3c事件模型执行原理

首先要了解事件处理的三个阶段:事件捕获—-》目标阶段—-》事件冒泡阶段

这里写图片描述

也就是说,任何发生在 w3c事件模型 中的事件,无论是冒泡事件还是捕获事件,元素都会先进入捕获阶段,直到达到目标元素,再进入冒泡阶段。

1. 捕获阶段
当我们在 DOM 树的某个节点发生了一些操作(例如单击、鼠标移动上去),就会有一个事件发射过去。这个事件从 Window 发出,不断经过下级节点直到目标节点。在到达目标节点之前的过程,就是捕获阶段(Capture Phase)。

所有经过的节点,都会触发这个事件。捕获阶段的任务就是建立这个事件传递路线,以便后面冒泡阶段顺着这条路线返回 Window。

监听某个在捕获阶段触发的事件,需要在事件监听函数传递第三个参数 true。

element.addEventListener(<event-name>, <callback>, true);

2. 目标阶段(Target Phase)
当事件跑啊跑,跑到了事件触发目标节点那里,最终在目标节点上触发这个事件,就是目标阶段。

需要注意的时,事件触发的目标总是最底层的节点。

3. 冒泡阶段(Bubbling Phase)
当事件达到目标节点之后,就会沿着原路返回,由于这个过程类似水泡从底部浮到顶部,所以称作冒泡阶段。

仍然以上面的代码为例子,假设目标元素为four,也就是four被点击,执行结果是一样,那么它的执行过程呢?
如下代码:

one.addEventListener('click',function(){
    alert('one');
},true);
two.addEventListener('click',function(){
    alert('two');
},false);
three.addEventListener('click',function(){
    alert('three');
},true);
four.addEventListener('click',function(){
    alert('four');
},false);

其实过程就是,从four元素的最顶层的祖先开始向下判断是否有捕获事件的元素,从上往下,如有捕获事件,则执行;一直向下到目标元素后,从目标元素开始向上执行冒泡元素,即第三个参数为false的绑定事件的元素。(在向上执行过程中,已经执行过的捕获事件不再执行,只执行冒泡事件。)

此时点击four元素,four元素为目标元素,one为根元素祖先,从one开始向下判断执行。

  • one为捕获事件,输出one;
  • two为冒泡事件,忽略;
  • three为捕获时间,输出three;
  • four为目标元素,开始向上冒泡执行,输出four;(从此处分为两部分理解较容易。)
  • three为捕获已执行,忽略;
  • two为冒泡事件,输出two;
  • one为捕获已执行,忽略。

最终执行结果为:one three four two 。简单理解就是先从上到下输出ture的,然后在反过来输出flase的。

(在这里可能会有疑问,目标元素是什么事件有区别吗?我的测试结果是没有区别的,无论目标元素是捕获还是冒泡,在w3c下都是先从根元素执行捕获到目标元素,再从目标元素向上执行。)

有疑问的话可以在这个例子上将其他三个元素作为目标元素测试。

例如,three作为目标元素,执行结果为:one three two(因为two是冒泡事件,在向下执行时没有执行到。)

2.5 多个事件绑定的执行顺序

最后就是讨论一个DOM元素绑定多个事件的执行过程。

执行次数:绑定了几个事件便执行几次。

如下代码,two元素绑定了两个不同事件,点击two都会执行这两个事件。而执行顺序有所差异

1、如果two为目标元素,目标元素的事情按顺序执行,而其他元素根据W3C的标准执行,即先捕获后冒泡。

【是目标元素】点击two执行结果:one(因为是two的父元素支持捕获事件所以先执行) two,bubble two,capture(顺序执行,注意逗号不是间隔,是输出内容。)

2、如果目标元素不是two,则two的两个事件按先捕获后冒泡触发执行,也就是跟前面讨论的执行过程是一样的,只不过两个事件都绑定在同一个DOM元素上。

【不是目标元素】点击three执行结果:one—— two,capture—– three,bubble———-two,bubble

one.addEventListener('click',function(){
    alert('one');
},true);
two.addEventListener('click',function(){
    alert('two,bubble');
},false);
two.addEventListener('click',function(){
    alert('two,capture');
},true);
three.addEventListener('click',function(){
    alert('three,bubble');
},true);
four.addEventListener('click',function(){
    alert('four');
},true);

大多数情况下,程序需要对事件冒泡进行取消?

取消事件冒泡

IE:

window.event.cancelBubble=true;

W3C:

function(event){
    event.stopPropagation();
}

解决兼容性问题: public.js

这里写图片描述

3. 事件对象

1)什么是事件对象
事件对象就是事件发生时系统自动产生的对象,这个对象包含了这个事件发生时所有的信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值