浅谈事件冒泡和事件捕获,js之事件冒泡和事件捕获详细介绍

By admin in 4858美高梅 on 2019年3月25日

第贰我们的话说哪些是事件冒泡

背景知识

① 、冒泡型事件

事件依据从最标准的对象到最不确切的指标的顺序触发。差异浏览器的顺序有所不一致。
IE 5.5: div -> body -> document
IE 6.0: div -> body -> html -> document
Mozilla 1.0: div -> body -> html -> document -> window

(1)冒泡型事件:事件依据从最特定的轩然大波指标到最不特定的事件指标(document对象)的依次触发。

浅谈事件冒泡和事件捕获,js之事件冒泡和事件捕获详细介绍。    事件冒泡:子级寻找父级的经过

怎么样是事件?
直观的说就是网页上爆发的事情,超过六分之三是指用户的鼠标动作和键盘动作,如点击、移动鼠标、按下有个别键。为啥说抢先八分之四吗,因为事件不单单只有那两有个别,还有其余的比如document的load和unloaded。只不过我们尤其关心的是用户的操作。

事件模型:规范事件的定义的一种标准

事件的三种模型:

二 、捕获型事件

事件从最不纯粹的指标初叶接触,然后到最可信赖对象。

  IE 5.5: div -> body -> document

                     
当子级触发事件时,这一个事件会形成二个时间流,这些事件流会稳步的上扬传播,

  • 土生土长事件模型(DOM 0级事件模型)
  • IE事件模型
  • 4858美高梅 ,DOM2事件模型

三、DOM事件流

还要协助二种事件模型:捕获型事件和冒泡型事件,可是,捕获型事件先爆发。三种事件流会触及DOM中的全体目标,从document对象开端,也在document对象甘休。

  IE 6.0: div -> body -> html -> document

                      所经过的父级的和子级相同的轩然大波会被实践

DOM2事件模型:
DOM事件模型最特殊的性质是,文本节点也触及事件(在IE中不会)。
  • 支撑W3C标准的浏览器在增加事件时用add伊夫ntListener(event,fn,useCapture)方法,基中第三个参数useCapture是贰个Boolean值,用来设置事件是在事件捕获时进行,照旧事件冒泡时执行。
  • 不包容W3C的浏览器(IE)用attach伊夫nt()方法,此办法没有有关设置,可是IE的风云模型默许是在事件冒泡时执行的,也正是在useCapture等于false的时候实施,所以把在处总管件时把useCapture设置为false是比较安全,也完毕兼容浏览器的功用。

4858美高梅 1

示意图

  Mozilla 1.0: div -> body -> html -> document -> window

   事件捕获:父级查找子级的进度叫事件捕获

此模型是W3C制定的行业内部模型,既然是正经,那我们都得按这几个来,大家明日应用的当代浏览器(指IE6~8除此而外的浏览器)都曾经依据那一个标准。W3C制定的风云模型中,“DOM2级事件”中分明的轩然大波流同时支持了事件捕获阶段和事件冒泡阶段,而作为开发者,大家得以接纳事件处理函数在哪2个阶段被调用。
贰次事件的发出包蕴多少个经过:

假定三个要素div,个中富含一个成分p。

<div>
  <p>元素</p>
</div>

那三个元素都绑定了click事件,假设用户点击了p,它在div和p上都接触了click事件,那那多个事件处理程序哪个先实施吗?事件顺序是什么样?

(2)捕获型事件(event capturing):事件从最不精确的指标(document
对象)初阶接触,然后到最规范(也足以在窗口级别捕获事件,不过必须由开发人士尤其内定)。

                    
当子级触发一个轩然大波时会触发事件流,那一个事件流会从父级传递到子级,所通过的

(1)capturing phase:事件捕获阶段。
事件被从document平素向下传播到对象成分,在那进程中逐条检查通过的节点是或不是注册了该事件的监听函数,若有则进行。

(2)target phase:事件处理阶段。
事件到达目的成分,执行对象成分的事件处理函数.

(3)bubbling phase:事件冒泡阶段。
事件从指标成分上涨一向到达document,同样依次检查通过的节点是还是不是注册了该事件的监听函数,有则履行。

>在此以前Netscape和Microsoft是见仁见智的完毕情势

  • Netscape中,div先触发,那就称为事件捕获。事件捕获当你使用事件捕获时,父级成分先触发,子级成分后触发,即div先触发,p后接触。
  • Microsoft中,p先触发,那就称为事件冒泡。事件冒泡当你使用事件冒泡时,子级成分先触发,父级成分后触发,即p先触发,div后触发。
  • 二种事件处理顺序刚好相反。IE只帮忙事件冒泡,Mozilla, Opera 7 和
    Konqueror二种都援助,旧版本的Opera’s 和 iCab三种都不协助 。

(3)DOM事件流:同时协理三种事件模型:捕获型事件和冒泡型事件,可是,捕获型事件先爆发。三种事件流会触及DOM中的全体目的,从document对象初阶,也在document对象甘休。

                     所有子级的相同事件会被触发

负有的风云类型都会经历captruing
phase(事件捕获),不过唯有部分事件会经历bubbling
phase(事件冒泡)阶段,例如submit事件就不会被冒泡。

W3C模型

W3C模型是将两边进行和平,在W3C模型中,任何事件发生时,先从顶层早先展开事件捕获,直到事件触发到达了事件源元素。然后,再从事件源往上拓展事件冒泡,直到抵达document。程序员能够友善采纳绑定事件时使用事件捕获还是事件冒泡,方法正是绑定事件时通过add伊芙ntListener函数,它有四个参数,第一个参数假若true,则代表选用事件捕获,若是false,则代表选择事件冒泡。

IE浏览器如上边所说,IE只帮助事件冒泡,不协助事件捕获,它也不扶助add伊芙ntListener函数,不会用第多个参数来表示是冒泡如故捕获,它提供了另一个函数attach伊芙nt。

ele.attachEvent("onclick", doSomething2);

  DOM事件模型最奇特的性质是,文本节点也接触事件(在IE中不会)。

 

1. 是什么?

<div id="outer">
    <p id="inner">Click me!</p>
</div>

下面包车型地铁代码在那之中三个div成分当中有二个p子成分,假诺多少个成分都有二个click的处理函数,那么大家怎么才能知道哪2个函数会率先被触发呢?

为了化解那一个标题微松软网景建议了二种差不多统统相反的定义。

**事件流 : ** 指的是页面中收受事件的顺序.

注意:

支撑W3C标准的浏览器在添加风浪时用add伊夫ntListener(event,fn,useCapture)方法,基中第三个参数
useCapture是2个Boolean值,用来设置事件是在事变捕获时实施,仍轶事件冒泡时执行。而不般配W3C的浏览器(IE)用
attach伊夫nt()方法,此办法没有相关安装,但是IE的风云模型暗许是在事变冒泡时执行的,也正是在useCapture等于false的时候
执行,所以把在处总管件时把useCapture设置为false是比较安全,也兑现兼容浏览器的功效。

事件冒泡是由IE提议,而事件捕获是由网景提议

事件冒泡

微软提出了名为事件冒泡(event bubbling)的事件流。
事件冒泡能够形象地比喻为把一颗石头投入水中,泡泡会从来从水底冒出水面。

当2个DOM成分上的事件被触发的时候(如:按钮点击事件),那几个成分的兼具父成分中,要是也绑定有该相同事件,则也会被触发, 触发的次第正是先从 :
当前成分的风云 ==> 临近父成分 ==>
父成分……,这一经过被称之为事件冒泡

因此地点的事例在事件冒泡的概念下产生click事件的逐条应该是:
p -> div -> body -> html -> document
IE,火狐和chrome浏览器都以事件冒泡.

事件冒泡(的长河)

事件从爆发的靶子(event.srcElement||event.target)开头,沿着文书档案逐层向上冒泡,到document甘休。

4858美高梅 2

 

事件捕获

网景提出另一种事件流名为事件捕获(event capturing)。
当2个DOM成分上的风浪被触发的时候(如:按钮点击事件),那些因素的具有父成分中,假设也绑定有该相同事件,则也会被触发, 触发的逐一正是先从 : …….
父成分 ==> 临近父成分 ==> 当前因素的事件,这一经过被称之为事件捕获
与事件冒泡相反,事件会从最外层开头发生,直到最具体的成分。
地点的例子在事件捕获的定义下发出click事件的逐条应该是:
document -> html -> body -> div -> p

图解:

4858美高梅 3

事件冒泡和破获具体如图

事件的传遍是足以阻止的:

• 在W3c中,使用stopPropagation()方法;
• 在IE下设置cancelBubble = true;;
在捕获的经过中stopPropagation();末尾的冒泡进度也不会时有爆发了。

事件捕获阶段:事件从最上超级标签开始往下搜寻,直到捕获到事件目的(target)。
事件冒泡阶段:事件从事件指标(target)起初,往上冒泡直到页面包车型大巴最上拔尖标签。

由地点那句话能够看出来3个难题

2. 消除了什么难题?

那多个概念都以为了消除页面中事件流(事件产生顺序)的题材。

http://www.imooc.com/article/9833

掣肘事件的私下认可行为,例如a标签点击后的跳转

• 在W3c中,使用preventDefault()方法;
• 在IE下设置window.event.returnValue = false;;
不是兼具的轩然大波都能冒泡,例如:blur、focus、load、unload.

若果2个成分div,它有三个部属成分p。
<div>
  <p>元素</p>
</div>
那四个因素都绑定了click事件,倘诺用户点击了p,它在div和p上都接触了click事件,那这三个事件处理程序哪个先实好吗?事件顺序是何等?
 
三种模型
先前,Netscape和Microsoft是见仁见智的兑现方式。

IE的破获机制和其余的浏览器捕获有如何两样:  IE只有事件冒泡,而正规浏览器既有事件捕获和事件冒泡

3. 履行原理

<ul>
   <li>
       <p>
          <a>  </div>
      </p>
   </li>
</ul>

4858美高梅 4

事件冒泡和事件捕获原型图

事件捕获阶段:事件从最上一流标签开始往下搜寻,直到捕获到事件目的(target)。
事件冒泡阶段:事件从事件指标(target)发轫,往上冒泡直到页面包车型地铁最上顶级标签。

事件捕获当你选用事件捕获时,父级成分先触发,子级成分后触发,即div先触发,p后接触。
事件冒泡当你利用事件冒泡时,子级成分先触发,父级元素后触发,即p先触发,div后触发。

Netscape中,div先触发,那就叫做事件捕获。

 

4. 如何使用?

说到事件的进行种种,那么大家需求精晓一个给元素添加事件的艺术,
即给某成分动态绑定事件
W3C为大家提供了addEventListener()函数用来为钦点的dom成分动态绑定事件。

语法:
element.addEventListener( event ,  function ,  useCapture )

4858美高梅 5

参数分析

提示: 使用 remove伊夫ntListener()方法来移除 add伊芙ntListener()
方法添加的事件句柄。

function sayHello() { 
console.log("hello");
}
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("click", sayHello);

这样我们点击id为myDiv的元素时,控制台就会输出"Hello"。

Microsoft中,p先触发,那就称为事件冒泡。

 

事件冒泡

有如下html代码:

4858美高梅 6

html代码

4858美高梅 7

运行结果

上边安装了多少个函数用来开始展览事件绑定:

4858美高梅 8

要绑定的函数

使用上面包车型客车代码,大家得以获得多个要素对应DOM

4858美高梅 9

四个DOM元素

昨天,小编试着还要分别为grandpa和grandson绑定sleep和doingHomework事件:

4858美高梅 10

绑定事件

此时大家点击最外层的grandpa时,当然会触发sleep函数,不过当大家点击grandson时,控制台的输出如下:

4858美高梅 11

控制台查看结果

案由:那是因为grandson在grandpa之上,当点击grandson时,同时也在grandpa上开始展览了点击操作,所以在实践了doingHomework后,还会触发grandpa的sleep函数。
那种当满足条件后从子成分到父成分依次触发其上事件的处理格局叫做事件冒泡

咱俩也为father和child分别绑定watchTV和playingCard函数

4858美高梅 12

绑定事件

4858美高梅 13

控制台查看结果

事件冒泡()
grandpa.addEventListener("click", sleep);            
grandson.addEventListener("click", doingHomework);            
father.addEventListener("click", watchTV);            
child.addEventListener("click", playingCard);

4858美高梅 14

八个成分都绑定相同事件,点击grandson时的结果

4858美高梅 15

点击child元素的 结果

二种事件处理顺序刚好相反。IE只协监护人件冒泡,Mozilla, Opera 7 和
Konqueror三种都援助,旧版本的Opera’s 和 iCab两种都不帮忙 。

前几日又有贰个难点,当事件冒泡和事件捕获同时发生时会爆发什么样意况呢

事件捕获

事件捕获与事件冒泡完全相反,先触发祖先成分的风云,然后再逐级触发子成分的风云。私下认可情形下,绑定事件时,选择事件冒泡原则,假使想要进行事件捕获的话,需求安装3个参数

能够为add伊夫ntListener函数添加第⑩个参数useCapture,参数值是布尔值,暗许是false。当useCapture为false时,事件处理选拔事件冒泡的口径,当userCapture为true时,则应用事件捕获的尺度

4858美高梅 16

绑定捕获事件

那时,当点击grandson时,就会先实施祖先成分的风云,再履行后代元素的轩然大波了,控制台的输出如下图所示:

4858美高梅 17

破获事件的施行结果

固然如此私下认可情形下,useCapture的值是false,但笔者推荐大家在绑定函数时把它显然的写出来防止止浏览器包容性的标题。

事件捕获 当你使用事件捕获时,父级元素先触发,子级成分后触发,即div先触发,p后接触。

   
    先进行捕获后执行冒泡

事件冒泡与事件捕获假设同时开始展览如何是好

有思想的同桌肯定会考虑那样一个题材,在上述绑定事件的代码中,第一个参数不是成套装置的true,正是成套装置成false,那要是既有true,又有false,有的成分设置成按事件冒泡处理,有的成分设置成按事件捕获处理,那如何做吧?
平素告知我们答案,大家的浏览器更“喜爱”事件捕获:

它会先把useCapture为false的因素绑定事件放到一边,根据事件捕获符合规律的逐一执行useCapture为true的要素绑定事件,最终在根据事件冒泡顺序执行useCapture为false。
现行反革命大家作如下改变

4858美高梅 18

既有事件冒泡又有事件捕获

依据上述条件,当点击grandson时,先进行useCapture为true的成分的绑定事件,又根据事件捕获原则,先实施grandpa的风浪,再实行child的风浪。之后,再依据事件捕获顺序执行useCapture为false的轩然大波,输出结果如下:

4858美高梅 19

细说add伊夫ntListener与事件捕获、事件冒泡_

事件冒泡 当你利用事件冒泡时,子级成分先触发,父级成分后触发,即p先触发,div后触发。

 

阻拦事件冒泡和破获

笔者们能够动用时间对象event的stopPropagation()主意阻碍事件的更为传播。
笔者们修改一下doingHomework函数:

4858美高梅 20

为grandson的事件设置阻碍事件指标

4858美高梅 21

安装阻碍事件后,点击grandson的结果

发觉事件实施到doingHomework就被堵嘴了,其后不会在事件传播到父成分。
值得注意的是,event.stopPropagation()函数并不会阻止其下函数内容的施行。

*如果您采用的是jquery的轩然大波绑定,也足以直接在函数中选用return
false来阻止事件的流传(当然event.stopPropagation同样有效),与event.stopPropagation分歧的是,return
false会阻止同函数上边包车型客车代码执行 *

历史观绑定事件措施在1个援救W3C
DOM的浏览器中,像那样一般的绑定事件措施,是选择的轩然大波冒泡格局。
ele.onclick = doSomething2

IE浏览器
如上面所说,IE只支持事件冒泡,不帮忙事件捕获,它也不支持add伊夫ntListener函数,不会用第⑦个参数来代表是冒泡依然捕获,它提供了另2个函数attach伊芙nt。
ele.attachEvent("onclick", doSomething2);

不是装有的事件都能冒泡,例如:blur、focus、load、unload。

事件冒泡的利益

  • 我在github上的demo

W3C模型 W3C模型是将两端实行平和,在W3C模型中,任何事件时有产生时,先从顶层初阶展开事件捕获,直到事件触发到达了事件源成分。然后,再从事件源往上进展事件冒泡,直到抵达document。

程序员能够协调挑选绑定事件时利用事件捕获依然事件冒泡,方法正是绑定事件时经过add伊芙ntListener函数,它有四个参数,第捌个参数即使true,则意味着采纳事件捕获,要是false,则意味着选拔事件冒泡。

ele.addEventListener(‘click’,doSomething2,true)

true=捕获

false=冒泡

古板绑定事件措施 在3个支撑W3C
DOM的浏览器中,像这么一般的绑定事件措施,是接纳的风云冒泡格局。

ele.onclick = doSomething2

IE浏览器 如上边所说,IE只帮助事件冒泡,不援助事件捕获,它也不支持add伊芙ntListener函数,不会用第二个参数来表示是冒泡照旧捕获,它提供了另三个函数attach伊芙nt。

ele.attachEvent(“onclick”, doSomething2);

附:事件冒泡(的经过):事件从爆发的对象(event.srcElement||event.target)开头,沿着文书档案逐层向上冒泡,到document结束。

事件的扩散是足以阻止的: • 在W3c中,使用stopPropagation()方法
• 在IE下设置cancelBubble = true;
在捕获的历程中stopPropagation();后,前边的冒泡进程也不会爆发了~
3.挡住事件的暗中同意行为,例如click <a>后的跳转~
• 在W3c中,使用preventDefault()方法;
• 在IE下设置window.event.returnValue = false;
4.哇,终于写完了,一边测试一边写的额,不是拥有的风浪都能冒泡,例如:blur、focus、load、unload,(这么些是从别人的稿子里摘过来的,笔者没测试)。

 

 

 

例如:

  事件机制默许是从子向父,传到某些成分的时候假若没有点名是捕获会接纳冒泡。

(1)事件冒泡:(从子向父)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="jquery-1.8.3.js"></script>
    <script>
/*        $(document).click(function () {
            alert("document点击!!!!");
        })*/
        $(function () {
//            window.preventDefault();
//            window.preventBubble();
//            window.stopPropagation();
            $("div").click(function () {
                alert("div点击");
            });
          $("p").click(function () {
                alert("p被点击");
            });
            $(document)[0].addEventListener('click',function () {
                alert("document点击!!!!");
            },false)
        });

    </script>
</head>
<body>
<div>
    <p>p1</p>
    <p>p2</p>
</div>


</body>
</html>

  

结果:点击P1的时候

4858美高梅 22

4858美高梅 23

4858美高梅 24

 

 

 

 (2)事件捕获:(从父向子)** 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="jquery-1.8.3.js"></script>
    <script>
        $(function () {
            $("p").click(function () {
                alert("p被点击");
            });
            $(document)[0].addEventListener('click', function () {
                alert("document点击!!!!");
            }, true)
            $("div")[0].addEventListener('click', function () {
                alert("div点击!!!!");
            }, true)
        });

    </script>
</head>
<body>
<div>
    <p>p1</p>
    <p>p2</p>
</div>


</body>
</html>

结果:点击P1的时候

4858美高梅 25

 

4858美高梅 26

4858美高梅 27

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有