JavaScript中的两种事件流

JavaScript中的两种事件流

  事件流描述的是从页面中接收事件的顺序。提出事件流概念的正是IE和Netscape,但是前者提出的是我们常用的事件冒泡流,而后者提出的是事件捕获流。

第一部分:事件冒泡

  即事件开始由最具体的元素接收,然后逐级向上传播到较为不具体的节点(文档)。

  下面举一个简单的例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>bubble</title>
    <style>
        button{
            background: red;
            color:white;
        }
        #third{
            width: 50px;
            height: 50px;
            border:thin solid red;
        }
        #second{
            width: 100px;
            height: 100px;
            border:thin solid red;
        }
        #first{
            width:200px;
            height: 200px;
            border:thin solid red;
        }
    </style>
</head>
<body>
    <div id="first">
        <div id="second" >
            <div id="third" >
                <button id="button">事件冒泡</button>
            </div>
        </div>
    </div>
    <script>

        document.getElementById("button").addEventListener("click",function(){
            alert("button");
        },false);

        document.getElementById("third").addEventListener("click",function(){
            alert("third");
        },false);

        document.getElementById("second").addEventListener("click",function(){
            alert("second");
        },false);        

        document.getElementById("first").addEventListener("click",function(){
            alert("first");
        },false);

    </script>
</body>
</html>

这时,我们只点击button元素,效果如下:

可以看到,虽然我们只点击了button元素,但是,button外的third、second、first上的事件由内向外以此被触发,触发的顺序是由DOM树的下层到DOM树的最上面,故称为冒泡

说明:尽管这里我使用了DOM2级事件处理程序,并设置每个事件为冒泡阶段发生,但是即使使用DOM0级,得到的结果也是这样的,冒泡是默认的

但是如果我们不希望事件冒泡呢?那么如何阻止事件冒泡

实际上,事件的对象有一个stopPropagation()方法可以阻止事件冒泡,我们只需要把上个例子中button的事件处理程序修改如下:

        document.getElementById("button").addEventListener("click",function(event){
            alert("button");
            event.stopPropagation();
        },false);

这样,点击button后,只会弹出一个弹窗,显示button.

注意:现代所有的浏览器都支持事件冒泡,只是在实现上有一些差别。

第二部分:事件捕获

  事件捕获和事件冒泡是刚好相反的,事件捕获是指不太具体的节点应该更早的接收到事件,而最具体的节点应该最后接收到事件。举例如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>bubble</title>
    <style>
        button{
            background: red;
            color:white;
        }
        #third{
            width: 50px;
            height: 50px;
            border:thin solid red;
        }
        #second{
            width: 100px;
            height: 100px;
            border:thin solid red;
        }
        #first{
            width:200px;
            height: 200px;
            border:thin solid red;
        }
    </style>
</head>
<body>
    <div id="first">
        <div id="second" >
            <div id="third" >
                <button id="button">事件冒泡</button>
            </div>
        </div>
    </div>
    <script>

        document.getElementById("button").addEventListener("click",function(){
            alert("button");
        },true);

        document.getElementById("third").addEventListener("click",function(){
            alert("third");
        },true);

        document.getElementById("second").addEventListener("click",function(){
            alert("second");
        },true);        

        document.getElementById("first").addEventListener("click",function(){
            alert("first");
        },true);

    </script>
</body>
</html>

大家可以看到这个例子我只是把addEventListener()方法的第三个参数由前面例子的false修改为了true,也就是使用捕获方式获得button,那么结果如下:

我们可以看到最外层的事件先被触发,最后才是我们点击的button事件被触发,这便是事件捕获。

注意:尽管这是Netscape Navigator提出的事件流,但是现在所有的浏览器都支持这种事件流模型。但是由于老的浏览器不支持,所以很少有人使用事件捕获。

第三部分:DOM事件流

  DOM2级事件规定的时间流包括 三个阶段:

  • 事件捕获阶段
  • 处于目标阶段
  • 事件冒泡阶段

  注意:在DOM事件流中,实际的目标在捕获阶段不会接收到事件,下一个阶段是处于目标阶段,这时事件被触发,最后进入事件冒泡阶段。我们认为处于目标阶段是事件冒泡阶段的一部分。

时间: 2024-10-23 20:46:58

JavaScript中的两种事件流的相关文章

探究JavaScript中的五种事件处理程序

我们知道JavaScript与HTML之间的交互是通过事件实现的.事件最早是在IE3和Netscape Navigator 2中出现的,当时是作为分担服务器运算负载的一种手段. 通俗地理解,事件就是用户或浏览器自身执行的某种操作.而事件处理程序即为响应某个事件的函数.抽出主干,即事件处理程序为函数.  我们又把事件处理程序称为事件侦听器.  事件处理程序是以"on"开头的,因此对于事件on的时间处理程序即为onclick.时间处理程序在JavaScript中大致有五种,下面会根据这五种

javascript中对象两种创建方式

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript"> // 创建对象的两种方式: // 1 对象字面量 // 2 new Obj

在Javascript中监听flash事件(转)

在Javascript中监听flash事件,其实有两种做法: 1.在特定的环境下(例如专门制作的flash),大家约定一个全局函数,然后在flash的事件中用ExternalInterface.call调用这个全局函数即可.2.在非特定的环境下(例如编写通用的flash插件),是不能限制用户的函数名的,所以根本无法约定全局函数:是否可以通过类似js的回调函数的形式实现事件监听呢? 其实js与flash的通信,一般情况下可以进行一些比较简单的通信,如传递基本的数据类型.传递简单的对象.调用函数等,

实现一个函数clone,使JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制

实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number.String.Object.Array.Boolean)进行值复制. 1 /** 对象克隆 2 * 支持基本数据类型及对象 3 * 递归方法 */ 4 function clone(obj) { 5 var o; 6 switch (typeof obj) { 7 case "undefined": 8 break; 9 case "string": o = obj + &q

JavaScript中的三种弹出对话框

JavaScript中的三种弹出对话框 *****本文来自互联网****** 学习过js的小伙伴会发现,我们在一些实例中用到了alert()方法.prompt()方法.prompt()方法,他们都是在屏幕上弹出一个对话框,并且在上面显示括号内的内容,使用这种方法使得页面的交互性更精彩,实际上我们经常会在进行网页浏览时简单这种类型的对话框,在用户与应用程序进行双向交流时,经常要用到对话框.avascript的三种对话框是通过调用window对象的三个方法alert(),confirm()和prom

JavaScript中的两个“0”(翻译)

本文翻译自JavaScript’s two zeros JavaScript has two zeros: −0 and +0. This post explains why that is and where it matters in practice. JavaScript 中有两个“0”: -0 和 +0 .这篇文章解释了为什么,并且指出实际生产中会造成什么影响 1.The signed zero 1.“-0” Numbers always need to be encoded to b

Crystal Report在.net中的两种显示方式

原文:Crystal Report在.net中的两种显示方式 编写人:CC阿爸 2014-7-29 近来在完成深圳一公司的项目,对方对各方面要求相当严格,一不满意就拒绝签收,为了对修正水晶报表显示及导出的一些小问题,无赖之下,仔细了解一下水晶报表的操作方法,逼苦我们这些苦逼的程序,虽说在以前的项目中,也常使用crystal report 来制作报表.并且针对web与winform 都各有不同的地方. 但总的来讲:显示水晶报表目前使用控件对象的有两种显示方式 1.      使用crystalRe

JavaScript中的两个“0” -0和+0

JavaScript中的两个"0"(翻译) 本文翻译自JavaScript's two zeros JavaScript has two zeros: ?0 and +0. This post explains why that is and where it matters in practice. JavaScript 中有两个"0": -0 和 +0 .这篇文章解释了为什么,并且指出实际生产中会造成什么影响 1.The signed zero 1."

Linux中的两种link方式

Linux系统中包括两种链接方式:硬链接(hard link)和符号链接(symbolic link),其中符合链接就是所谓的软链接(soft link),那么两者之间到底有什么区别呢? inode 在Linux系统中,内核为每一个新创建的文件分配一个inode,每个文件都有一个惟一的inode,这里将inode简单理解成一个指针,它永远指向本文件的具体存储位置同时,文件属性保存在inode里,比如owner等.在访问文件时,inode被复制到内存,从而实现文件的快速访问.系统是通过inode来