Home > Web Front-end > JS Tutorial > Event bubbling and time capture of JavaScript events (summary sharing)

Event bubbling and time capture of JavaScript events (summary sharing)

WBOY
Release: 2021-12-23 18:49:56
forward
2457 people have browsed it

This article brings you a detailed explanation of the basic knowledge about events in JavaScript, including event bubbling and time capture. I hope it will be helpful to everyone.

Event bubbling and time capture of JavaScript events (summary sharing)

1. Event bubbling and event capturing

When we click an element on the Web page, such as a p element. If you think about it carefully, we clicked not only this p element, but also the concentric circle elements with the p as the center, such as the parent of the element, the outer body, the parent element html of the body, and the outer element. layer document. The propagation of events among these nested elements is called event flow.

  • 1. Event bubbling
  • 2.Event capturing

1.Event bubbling

The event stream of IE is called Events bubble up, starting with the most specific element and propagating upward. The event handler we added using DOM0 is processed during the event bubbling stage. For example:

<html>
  <head>
    <script type="text/javascript">

      window.onload = bubblingHandle;      function bubblingHandle() {
          //内层p处理程序
          document.getElementById("inner").onmousedown     = function() {
              alert("inner p");
          }          //外层p处理程序
          document.getElementById("outer").onmousedown = function() {
              alert("outerp");
          }

          document.onmousedown = function() {
              alert("document");
          }
      } 
      -->    </script>
  </head>
  <body>
    <p id="outer" style="background-color:black; padding: 15px;">
        <p id="inner" style="background-color:white; padding: 5px;"></p>
    </p>
  </body></html>
Copy after login

When you click on the white p in the inner layer, it will be displayed in sequence:

inner p
outer p
document
Copy after login

Event capture

The event flow proposed by Netscape is called event capture , which is almost the opposite of IE. Events are first received by the least specific element and then propagated to specific nodes.

2. DOM0 level event processing

Events are triggered by some specific behaviors that occur in the WEB page. For example, when you press the left mouse button on a page element, press a keyboard key, or an object gains or loses focus, the corresponding event will be triggered. The interaction between JavaScript and HTML is achieved through events. We use event listeners to "register" events, and the corresponding code is executed when the event occurs.

DOM level 0 event handler is still supported by all browsers due to its simplicity and cross-browser support.

  • Specify event handler through DOM0 level method
  • this in event handler
  • Delete event handler through DOM0 level method

Specify event handlers through DOM0-level methods

The method of specifying event handlers through DOM0-level methods is very simple. First, obtain a reference to the element to be operated on, and then assign a function to the corresponding elementEvent handler properties. (Each element including window and document has its own event handler attribute.) Note that event handlers added in this way will be processed during the bubbling phase of the event flow.

Regarding the event handler attributes, the following points need to be explained:

1. The event handler attributes are all lowercase, starting with "on", followed by the event type:

onclick  //单击鼠标
onload  //图像或页面载入完成
onmouseover  //将鼠标移动到某元素上面
onmousemove  //移动鼠标
onfocus  //对象获得焦点
Copy after login

2. Each element such as img, a, input, form including window and document has its own event handler attribute. For example:

document.getElementById("btn1").onclick  //btn1上单击鼠标
document.getElementById("img1").onmouseover  //鼠标移动到img1
document.getElementById("img1").onmerror  //img1图像无法载入
Copy after login

Next, assign a value to the event handler attribute to complete the specification of the event handler method. For example, when the mouse moves to "img1", the dialog box "This is a nice pic!" pops up:

var pic1 = document.getElementById("img1");
pic1.onmouseover = function() {
    alert("This is a nice pic!");
};
Copy after login

Special note: If the above code is at the bottom of the document, when the page is just loaded, we will Move the mouse over img1. It is possible that because the code has not been executed yet, the dialog box we set will not pop up! Today, this delay is very short.

This

in the event handler is the event handler specified by the DOM0 level method and belongs to the element method. Therefore, our this in the event handler refers to that element! Illustrate through the following example:

<input id="btn1" type="button" value="Click Me" />
...//省略
<script type="text/javascript">
  <!--
  var btn1 = document.getElementById("btn1");
  btn1.onclick = function() {
      alert(this.id + "\n" + this.type + "\n" + this.value);
  };
  -->
</script>
Copy after login

Delete event handler through DOM0 level method

To delete an event handler, you only need to set the corresponding event handler attribute to null:

pic1.onmouseover = null;
Copy after login

3. DOM2-level event processing

1. addEventListener and removeEventListener

Currently, almost all browsers support the DOM0 event model, but developers are encouraged to use the new DOM2 model . There are two significant differences between the DOM2 model and DOM0:

  • 1. DOM2 does not rely on event handler attributes
  • 2. Multiple handlers can be registered for the same event of an object at the same time. Follow the registration order.

DOM2 defines 2 methods:

addEventListener()  //指定事件处理程序
removeEventListener()  //删除事件处理程序
Copy after login

All DOM nodes contain these two methods. The usage of these two methods is as follows. They both receive 3 parameters, the first To handle the event name (excluding on), the second event handler function, the third Boolean variable:

For example, we add 2 event handlers for the click event of button btn1, and the event handlers are in The event bubbling phase is processed:

<input id="btn1" type="button" value="Click Me" />
...
<script type="text/javascript">
  <!--
  var btn1 = document.getElementById("btn1");
  var handle1 = function() {
      alert("handle1!");
  }
  var handle2 = function() {
      alert("handle2!");
  }
  btn1.addEventListener("click", handle1, false);
  btn1.addEventListener("click", handle2, false);
  -->
</script>
Copy after login

When the btn1 button is clicked, a dialog box will pop up in sequence:

handle1!
handle2!
Copy after login

We can use the removeEventListener() method to delete the event handler we just specified. , pay attention to the parameters to be consistent:

btn1.removeEventListener("click", handle2, false);
Copy after login

Click the btn1 button at this time, only handle1! will be displayed.

It is important to note that if we use an anonymous function to specify an event handler, we cannot use the removeEventListener() method to delete the event handler:

 btn1.addEventListener("click", function(){
     alert("click!");
 }, false);

 btn1.removeEventListener("click", function(){
     alert("click!");
 }, false);  //无法取消!
Copy after login

这样是无法取消以上指定的事件处理程序的!因为上面addEventListener和removeEventListener中的2个事件处理函数虽然代码相同,实质上是2个不同的函数引用。

另外,强调一点,以上两个函数的第一个参数(要处理的事件名)是没有on前缀的。这一点和IE不同,后面会说明。

tips: IE9, Firefox, Safari, Chrome以及Opera均支持DOM2级事件处理程序。

DOM2事件处理程序中的this

DOM2事件处理程序和DOM0相同,它们的this都在其依附的元素作用域中运行。this的指代参考DOM0的示例。这里之所以要特别指出DOM2的this,是为了和IE事件处理程序进行区分。IE中事件处理程序this与事件指定方式有关。

四、IE事件处理程序及跨浏览器支持

attachEvent()与detachEvent()

IE并没有提供对W3C事件模型的支持,其实现了2个和DOM2模型类似的方法:

attachEvent()
detachEvent()
Copy after login

这两个方法只接收2个参数:事件名称以及事件处理函数。由于IE8及更早版本只支持事件冒泡,这两个方法添加的事件处理程序会在事件冒泡阶段被执行。

和DOM2不同的是:

  • 1、IE事件处理方法运行作用域为全局作用域,this指代window;
  • 2、第一个参数事件名以on为前缀;
  • 3、当为同一对象的相同事件指定多个处理程序时,执行顺序和DOM2相反,IE中以添加它们的相反顺序执行。

例如:

<input id="btn1" type="button" value="Click Me" />
...
<script type="text/javascript">
  <!--
  var btn1 = document.getElementById("btn1");
  var handle1 = function() {
      alert("handle1!" + "\n" + (this === window));
  };
  var handle2 = function() {
      alert("handle2!"+ "\n" + (this === window));
  };
  btn1.attachEvent("onclick", handle1);
  btn1.attachEvent("onclick", handle2);
  -->
</script>
Copy after login

执行结果:

handle2!
true

handle1!
true
Copy after login

跨浏览器支持

虽然可以使用屏蔽浏览器差异的JS库,实际上,我们自己编写一个跨浏览器兼容的事件处理代码并不是一件困难的事情,同时更有利于我们对原生JavaScript的学习理解。我们使用一个习惯上称为EventUtil的对象来进行跨浏览器事件处理:

var EventUtil = {
    addEventHandler : function(element, eventType,        handler) {
        if(element.addEventListener){
            element.addEventListener(eventType, handler, flase);
        } else if(element.attachEvent) {
            element.attachEvent("on" + eventType, handler);
        } else {
            element["on" + eventType] = handler;
        }
    },

    removeEventHandler : function(element, eventType, handler) {
        if(element.aremoveEventListener){
            element.addEventListener(eventType, handler, flase);
        } else if(element.detachEvent) {
            element.attachEvent("on" + eventType, handler);
        } else {
            element["on" + eventType] = null;
        }
    }
}
Copy after login

为了保证事件处理代码能够在大多数浏览器中一致地运行,我们这里只关注冒泡阶段。以上代码使用浏览器能力检测,首先检测是否支持DOM2级方法addEventListener和removeEventListener,如果支持则使用该方法;如果不支持该方法,检测是否是IE8级更早版本的attachEvent或detachEvent方法,若支持则使用该方法;如果对以上2种方法都不支持,则使用DOM0级方法。要注意,DOM0级对每个事件只能指定一个事件处理程序。

以上对象使用示例如下:

var btn1 = document.getElementById("btn1");var handle1 = function() {
    alert("handle1!" + "\n" + (this === window));
};var handle2 = function() {
    alert("handle2!"+ "\n" + (this === window));
};
EventUtil.addEventHandler(btn1, "click", handler1);
EventUtil.addEventHandler(btn1, "click", handler2);

EventUtil.removeEventHandler(btn1, "click", handler2);
Copy after login

五、事件对象

在触发某个事件时,会产生一个event对象。该对象中包含与事件有关的信息。例如触发事件的元素、事件的类型、与特定事件相关的如鼠标位置信息等。

  • 1、DOM事件对象
  • 2、IE事件对象与跨浏览器事件对象

1、DOM事件对象

不论使用DOM0级还是DOM2级方法指定事件处理程序,事件触发时都会自动将一个event对象传入事件处理程序,例如:

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

btn1.onmouseover = function(evnt) {
    alert(evnt.type);
}var handle = function(evnt) {
    alert(evnt.type);
};
btn1.addEventListener("click", handle, false);
Copy after login

以上是一个简单的event对象的示例。event对象中的type属性是一个只读字符串属性,其中包含着事件的类型。例如我们上例中的click和onmouseover。event对象中包含有大量的有关事件的属性和方法(例如event.stopPropagation()方法可用于停止事件在捕获或者冒泡阶段的继续传播,preventDefault()方法会取消阻止事件的行)在此就不一一列举了。其中常用的如下:

属性/方法值类型读写描述
currentTargetElementreadonly事件处理程序当前正在处理的元素
targetElementreadonly事件的目标
typeStringreadonly触发事件的类型
preventDefaultFunctionreadonly取消事件默认行为,如链接的默认行为就是被单击时跳转到href指定的url
stopPropagationFunctionreadonly取消事件进一步冒泡或捕获

2、IE事件对象与跨浏览器事件对象

IE事件对象

在IE中,当使用DOM0级指定事件处理程序时,event对象被认为是window的一个属性,例如获取鼠标点击坐标的代码:

var mouseLoc = function() {
    var loc = "x: " + window.event.screenX + "\n" +              "y: " + window.event.screenY;
    alert(loc);
};
Copy after login

当使用attachEvent()方法指定事件处理程序时,event对象会被作为参数传入事件处理程序,我们将以上的代码重写:

var mouseLoc = function(event) {
    var loc = "x: " + event.screenX + "\n" +              "y: " + event.screenY;
    alert(loc);
};
btn1.attachEvent("onclick",  mouseLoc);
Copy after login

IE中event对象的相关属性方法:

属性/方法值类型读写描述
cancelBubbleBooleanread/write默认为false,置为true时取消事件冒泡(同DOM中stopPropagation)
returnValueBooleanread/write默认为true,设为false取消事件默认行为(同DOM中preventDefault)
srcElementElementreadonly事件目标
typeStringreadonly事件类型

跨浏览器事件对象

解决跨浏览器问题的思路是一贯的,我们可以对浏览器进行能力检测,这里我们对上面的EventUtil对象进行扩展,对我们学习原生JS,这是一个很漂亮的对象:

var EventUtil = {
    addEventHandler : function(element, eventType, handler) {
        if(element.addEventListener){
            element.addEventListener(eventType, handler, flase);
        } else if(element.attachEvent) {
            element.attachEvent("on" + eventType, handler);
        } else {
            element["on" + eventType] = handler;
        }
    },

    removeEventHandler : function(element, eventType, handler) {
        if(element.aremoveEventListener){
            element.addEventListener(eventType, handler, flase);
        } else if(element.detachEvent) {
            element.attachEvent("on" + eventType, handler);
        } else {
            element["on" + eventType] = null;
        }
    },

    getEvent: function (event) {
        return event ? event : window.event;
    },

    getTarget: function (event) {
        return event.target || event.srcElement;
    },

    preventDefault: function (event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },

    stopPropagation: function (event) {
        if (event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubbles = true;
        }
    },

    getRelatedTarget: function (event) {
        if (event.relatedTarger) {            return event.relatedTarget;
        } else if (event.toElement) {            return event.toElement;
        } else if (event.fromElement) {            return event.fromElement;
        } else { return null; }
    }
}
Copy after login

【相关推荐:javascript学习教程

The above is the detailed content of Event bubbling and time capture of JavaScript events (summary sharing). For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:csdn.net
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template