Table of Contents
dom3事件处理程序
事件流的分类
那如果给同一元素同事绑定两个事件,一个采用冒泡一个采用捕获则程序会按照dom流的形式来执行程序即"先捕获后冒泡"
事件代理
Home Web Front-end JS Tutorial Detailed explanation of DOM event flow in js

Detailed explanation of DOM event flow in js

Mar 20, 2018 pm 05:46 PM
javascript event Detailed explanation

An event is some action performed by the user or the browser itself. Such as click, load, mouseover. Event flow describes the order in which events are received from the page, and can also be understood as the order in which events are propagated in the page. Event handler A function that responds to an event is called an event handler (or event listener).

DOM0 level event handler

The following example shows two methods for dom0 to bind events and how to unbind events. When executing the code, we find that if two events are bound to the same element at the same time If so, the event bound later will overwrite the event bound earlier.

<!DOCTYPE html>
<html>
<head>
   <meta charset="UTF-8">
   <title>Title</title>
</head>
<body>
       <button type="button" id="btn" onclick="alert(&#39;btn1&#39;)">点击按钮</button>
</body>
<script>    var btn=document.getElementById("btn");    //绑定事件    btn.onclick=function(){        alert("btn");
   };    //事件解绑    btn.onclick=null;
</script>
</html>
Copy after login

dom2 level event handler

<!DOCTYPE html>
<html>
<head>
   <meta charset="UTF-8">
   <meta name="viewport"          content="width=device-width, initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0,user-scalable=0"/>
   <title>Title</title>
</head>
<body>
<button type="button" id="btn" onclick="alert(&#39;btn1&#39;)">点击按钮</button>
</body>
<script>    var btn=document.getElementById("btn");    //绑定事件    btn.addEventListener("click",function(){         alert("btn");
   },false);    //事件解绑   btn.removeEventListener("click",function(){       alert("解绑");
  })
</script>
</html>
Copy after login

Note: The third parameter of the addEventListener() method defaults to false, that is, the program is executed in the form of event bubbling. If it is true, then Execution program in the form of event capture. Limited to non-IE browsers, IE browsers use attachEventListener to bind events. Regarding the binding and unbinding of events in IE and non-IE browsers, I will write an example to show the difference between the two.

var eventUtil = {    //添加事件    addEventHandle:function(element,eventType,fn){        if(element.addEventListener){//非IE            element.addEventListener(eventType,fn,false);
       }else if(element.attachEvent){//IE            element.attachEvent(&#39;on&#39;+eventType,fn);//这里拼接上&#39;on&#39;,调运的时候不要加on,使用click等。        }else{//不支持DOM2级,使用DOM0级方式            element[&#39;on&#39;+eventType] = fn;//这里使用[]方式实现对象的属性添加,相当于.的作用        }
   },    //删除事件    removeEventHandle:function(element,eventType,fn){        if(element.removeEventListener){//非IE,不带&#39;on&#39;            element.removeEventListener(eventType,fn,false);
       }else if(element.detachEvent){//IE,带&#39;on&#39;            element.detachEvent(&#39;on&#39;+eventType,fn);
       }else{//不支持DOM2级,使用DOM0级方式            element[&#39;on&#39;+eventType] = fn;
       }
   },    //获取事件对象    getEvent:function(event){        return event?event:window.event;
   },    //获取事件类型    getType:function(event){        return event.type;
   },    //获取执行事件的目标元素    getTarget:function(event){        return event.target||event.srcElement;
   },    //禁用默认行为    preventDefault:function(event){        if(event.preventDefault){            event.preventDefault();//非IE        }else{            event.returnValue = false;//针对IE        }

   },    //阻止传播冒泡    stopPropagation:function(event){        if(event.stopPrapagation){            event.stopPropagation();//非IE        }else{            event.cancelBubble = true;//针对IE        }
   }
}
Copy after login

dom3事件处理程序

DOM浏览器中可能发生的事件有很多种,不同事件类型具有不同的信息,DOM3级事件规定了一下几种事件:
UI事件,当用户与页面上的元素交互时触发;
焦点事件,当元素获得或者失去焦点时触发;
鼠标事件,当用户通过鼠标在页面上执行操作时触发;
滚轮事件,当使用鼠标滚轮(或类似设备)时触发;
文本事件,当在文档中,输入文本时触发;
键盘事件,当用户通过键盘在页面上执行操作时触发;
合成事件,当为IME(Input Method Editor,输入法编辑器)输入字符时触发;
变动事件,当底层Dom结构发生变化时触发;
DOM3级事件模块在DOM2级事件的基础上重新定义了这些事件,也添加了一些新事件。包括IE9在内的主流浏览器都支持DOM2级事件,IE9也支持DOM3级事件。
DOM中的事件模拟(自定义事件):
DOM3级还定义了自定义事件,自定义事件不是由DOM原生触发的,它的目的是让开发人员创建自己的事件。要创建的自定义事件可以由createEvent("CustomEvent");
返回的对象有一个initCustomEvent()方法接收如下四个参数。
1)type:字符串,触发的事件类型,自定义。例如 “keyDown”,“selectedChange”;
2)bubble(布尔值):标示事件是否应该冒泡;
3)cancelable(布尔值):标示事件是否可以取消;
4)detail(对象):任意值,保存在event对象的detail属性中;
可以像分配其他事件一样在DOM中分派创建的自定义事件对象。如:

   
var  p = document.getElementById("myp");
EventUtil.addEventHandler(p,"myEvent", function () {
alert("p myEvent!");
});
EventUtil.addEventHandler(document,"myEvent",function(){
alert("document myEvent!");
});
if(document.implementation.hasFeature("CustomEvents","3.0")){
var e = document.createEvent("CustomEvent");
e.initCustomEvent("myEvent",true,false,"hello world!");
p.dispatchEvent(e);
}
Copy after login

这个例子中创建了一个冒泡事件“myEvent”。而event.detail的值被设置成了一个简单的字符串,然后在p和document上侦听该事件,因为在initCustomEvent中设置了事件冒泡。所以当p激发该事件时,浏览器会将该事件冒泡到document。
IE中的事件模拟(IE8及之前版本中):
与DOM中事件模拟的思路类似,先创建event对象,再为其指定相应信息,然后再使用该对象来触发事件。当然IE在实现以下每个步骤都不太一样。
例如:

var btn = document.getElementById("myBtn");
//创建事件对象,不接受任何参数,结果会返回一个通用的event对象,你必须为该event对象指定所有必要的信息。
var event  = document.createEventObject();
//初始化事件对象
event.screenX = 100;
event.screenY = 0;
event.clientX = 0;
event.clientY =0;
event.ctrlKey = false;
event.altKey = false;
event.shiftKey = false;
event.button = 0;

//触发事件
btn.fireEvent("onclick",event);
Copy after login

事件流的分类

  • 事件冒泡流:IE的事件流叫事件冒泡,即事件开始时由最具体的元素(文档中嵌套层次最深的节点)接收,然后逐级向上传播到较为不具体的节点

  • 事件捕获流:Netscape团队提出的另一种事件流叫事件捕获,事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件

  • dom事件流:DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段==>处于目标阶段==>事件冒泡阶段。首先发生的是事件捕获阶段,为截获事件提供了机会。然后是实际的目标接收事件。最后一个阶段是冒泡阶段。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
       <p id="node1">
           <p id="node2">
               <p id="node3">
                   <p id="node4">click me</p>
               </p>
           </p>
       </p>
</body>
<script>    var node1=document.getElementById("node1");    var node2=document.getElementById("node2");    var node3=document.getElementById("node3");    var node4=document.getElementById("node4");    node1.addEventListener("click",function(){        alert("node1");
    },false);    node2.addEventListener("click",function(){        alert("node2");
    },false);    node3.addEventListener("click",function(){        alert("node3");
    },false);    node4.addEventListener("click",function(){        alert("node4");
    },false);
</script>
</html>
Copy after login

以上代码分别给node1-node4个节点绑定事件,且采用事件冒泡的形式执行,从而分别会弹出node4->node3->node3->node1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
       <p id="node1">
           <p id="node2">
               <p id="node3">
                   <p id="node4">click me</p>
               </p>
           </p>
       </p>
</body>
<script>    var node1=document.getElementById("node1");    var node2=document.getElementById("node2");    var node3=document.getElementById("node3");    var node4=document.getElementById("node4");    node1.addEventListener("click",function(){        alert("node1");
    },true);    node2.addEventListener("click",function(){        alert("node2");
    },true);    node3.addEventListener("click",function(){        alert("node3");
    },true);    node4.addEventListener("click",function(){        alert("node4");
    },true);
</script>
</html>
Copy after login

以上代码分别给node1-node4个节点绑定事件,且采用事件捕获的形式执行,从而分别会弹出node1->node2->node3->node4.

那如果给同一元素同事绑定两个事件,一个采用冒泡一个采用捕获则程序会按照dom流的形式来执行程序即"先捕获后冒泡"

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
       <p id="node1">
           <p id="node2">
               <p id="node3">
                   <p id="node4">click me</p>
               </p>
           </p>
       </p>
</body>
<script>    var node1=document.getElementById("node1");    var node2=document.getElementById("node2");    var node3=document.getElementById("node3");    var node4=document.getElementById("node4");    node1.addEventListener("click",function(){        alert("node1");
    },false);    node2.addEventListener("click",function(){        alert("node2");
    },false);    node3.addEventListener("click",function(){        alert("node3");
    },false);    node4.addEventListener("click",function(){        alert("node4");
    },false);    
    
    node1.addEventListener("click",function(){        alert("node1");
    },true);    node2.addEventListener("click",function(){        alert("node2");
    },true);    node3.addEventListener("click",function(){        alert("node3");
    },true);    node4.addEventListener("click",function(){        alert("node4");
    },true);
    
    
</script>
</html>
Copy after login

程序执行顺序:node1->node2->node3->node4->node4->node3->node2->node1.

事件代理

含义:事件代理即事件委托,就是利用事件冒泡只制定一个事件处理程序就可以管理某一类型的所有事件

为什么:一般来说,dom需要有事件处理程序,我们都会直接给它设事件处理程序就好了,那如果是很多的dom需要添加事件处理呢?比如我们有100个li,每个li都有相同的click点击事件,可能我们会用for循环的方法,来遍历所有的li,然后给它们添加事件,那这么做会存在什么影响呢?在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因;如果要用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能;

每个函数都是一个对象,是对象就会占用内存,对象越多,内存占用率就越大,自然性能就越差了(内存不够用,是硬伤,哈哈),比如上面的100个li,就要占用100个内存空间,如果是1000个,10000个呢,那只能说呵呵了,如果用事件委托,那么我们就可以只对它的父级(如果只有一个父级)这一个对象进行操作,这样我们就需要一个内存空间就够了,是不是省了很多,自然性能就会更好。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul id="ul1">
    <li>111</li>
    <li>222</li>
    <li>333</li>
    <li>444</li>
</ul>
<script>    //无事件代理    window.onload = function(){        var oUl = document.getElementById("ul1");        var aLi = oUl.getElementsByTagName(&#39;li&#39;);        for(var i=0;i<aLi.length;i++){            aLi[i].onclick = function(){                alert(123);
            }
        }
    };    //事件代理    window.onload = function(){        var oUl = document.getElementById("ul1");        oUl.onclick = function(ev){            var ev = ev || window.event;            var target = ev.target || ev.srcElement;            if(target.nodeName.toLowerCase() == &#39;li&#39;){                alert(123);                alert(target.innerHTML);
            }
        }
    }
</script>
</body>
</html>
Copy after login

相关推荐:

js中DOM事件绑定详解

JS中DOM如何操作

js中DOM知识点分享

The above is the detailed content of Detailed explanation of DOM event flow in js. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Detailed explanation of obtaining administrator rights in Win11 Detailed explanation of obtaining administrator rights in Win11 Mar 08, 2024 pm 03:06 PM

Windows operating system is one of the most popular operating systems in the world, and its new version Win11 has attracted much attention. In the Win11 system, obtaining administrator rights is an important operation. Administrator rights allow users to perform more operations and settings on the system. This article will introduce in detail how to obtain administrator permissions in Win11 system and how to effectively manage permissions. In the Win11 system, administrator rights are divided into two types: local administrator and domain administrator. A local administrator has full administrative rights to the local computer

Detailed explanation of division operation in Oracle SQL Detailed explanation of division operation in Oracle SQL Mar 10, 2024 am 09:51 AM

Detailed explanation of division operation in OracleSQL In OracleSQL, division operation is a common and important mathematical operation, used to calculate the result of dividing two numbers. Division is often used in database queries, so understanding the division operation and its usage in OracleSQL is one of the essential skills for database developers. This article will discuss the relevant knowledge of division operations in OracleSQL in detail and provide specific code examples for readers' reference. 1. Division operation in OracleSQL

Detailed explanation of the role and usage of PHP modulo operator Detailed explanation of the role and usage of PHP modulo operator Mar 19, 2024 pm 04:33 PM

The modulo operator (%) in PHP is used to obtain the remainder of the division of two numbers. In this article, we will discuss the role and usage of the modulo operator in detail, and provide specific code examples to help readers better understand. 1. The role of the modulo operator In mathematics, when we divide an integer by another integer, we get a quotient and a remainder. For example, when we divide 10 by 3, the quotient is 3 and the remainder is 1. The modulo operator is used to obtain this remainder. 2. Usage of the modulo operator In PHP, use the % symbol to represent the modulus

Detailed explanation of the linux system call system() function Detailed explanation of the linux system call system() function Feb 22, 2024 pm 08:21 PM

Detailed explanation of Linux system call system() function System call is a very important part of the Linux operating system. It provides a way to interact with the system kernel. Among them, the system() function is one of the commonly used system call functions. This article will introduce the use of the system() function in detail and provide corresponding code examples. Basic Concepts of System Calls System calls are a way for user programs to interact with the operating system kernel. User programs request the operating system by calling system call functions

Detailed explanation of Linux curl command Detailed explanation of Linux curl command Feb 21, 2024 pm 10:33 PM

Detailed explanation of Linux's curl command Summary: curl is a powerful command line tool used for data communication with the server. This article will introduce the basic usage of the curl command and provide actual code examples to help readers better understand and apply the command. 1. What is curl? curl is a command line tool used to send and receive various network requests. It supports multiple protocols, such as HTTP, FTP, TELNET, etc., and provides rich functions, such as file upload, file download, data transmission, proxy

Learn more about Promise.resolve() Learn more about Promise.resolve() Feb 18, 2024 pm 07:13 PM

Detailed explanation of Promise.resolve() requires specific code examples. Promise is a mechanism in JavaScript for handling asynchronous operations. In actual development, it is often necessary to handle some asynchronous tasks that need to be executed in sequence, and the Promise.resolve() method is used to return a Promise object that has been fulfilled. Promise.resolve() is a static method of the Promise class, which accepts a

How to implement change event binding of select elements in jQuery How to implement change event binding of select elements in jQuery Feb 23, 2024 pm 01:12 PM

jQuery is a popular JavaScript library that can be used to simplify DOM manipulation, event handling, animation effects, etc. In web development, we often encounter situations where we need to change event binding on select elements. This article will introduce how to use jQuery to bind select element change events, and provide specific code examples. First, we need to create a dropdown menu with options using labels:

Detailed analysis of C language learning route Detailed analysis of C language learning route Feb 18, 2024 am 10:38 AM

As a programming language widely used in the field of software development, C language is the first choice for many beginner programmers. Learning C language can not only help us establish the basic knowledge of programming, but also improve our problem-solving and thinking abilities. This article will introduce in detail a C language learning roadmap to help beginners better plan their learning process. 1. Learn basic grammar Before starting to learn C language, we first need to understand the basic grammar rules of C language. This includes variables and data types, operators, control statements (such as if statements,

See all articles