添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

addEventListener

EventTarget.addEventListener() 方法将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行。事件目标可以是一个文档上的元素 Element、Document 和 Window,也可以是任何支持事件的对象(比如 XMLHttpRequest),IE9 以下中为 attachEvent 替代。

推荐使用 addEventListener() 来注册一个事件监听器,理由如下:

  • 它允许为一个事件添加多个监听器。
  • 它提供了一种更精细的手段来控制 listener 的触发阶段(即可以选择捕获或者冒泡)。
  • 它对任何事件都有效,而不仅仅是 HTML 或 SVG 元素。
  • addEventListener(type, listener);
  • addEventListener(type, listener, options);
  • addEventListener(type, listener, useCapture);
  • 返回值:无(undefined)

    type: 事件名称,大小写敏感,不含“on”,比如“click”、“mouseover”、“keydown”等
    listener: listener 必须是一个实现了 EventListener 接口的对象,或者是一个函数。
    options 可选: 一个指定有关 listener 属性的可选参数对象。可用的选项如下:
    capture 可选 :布尔值,表示 listener 会在当前事件捕获阶段传播到该 EventTarget 时触发。默认值为 false。
    once 可选:布尔值,表示 listener 在添加之后最多只调用一次。如果为 true,listener 会在其被调用之后自动移除。默认值为 false。
    passive 可选:布尔值,设置为 true 时,表示 listener 永远不会调用 preventDefault()。如果设置false,同时用户在事件(touchstart/touchmove/touchend,是否还有其他事件未测试)中没有设置 event.preventDefault(),客户端将会忽略它并抛出一个控制台警告。默认值为 false。
    signal 可选:AbortSignal,该 AbortSignal 的 abort() 方法被调用时,监听器会被移除。默认值为 false。
    useCapture 可选: 布尔值,true 是事件捕获,false 是事件冒泡,默认false。表示在 DOM 树中注册了 listener 的元素,是否要先于它下面的 EventTarget 调用该 listener。当 useCapture(设为 true)时,沿着 DOM 树向上冒泡的事件不会触发 listener。当一个元素嵌套了另一个元素,并且两个元素都对同一事件注册了一个处理函数时,所发生的事件冒泡和事件捕获是两种不同的事件传播方式。事件传播模式决定了元素以哪个顺序接收事件。
    useCapture 触发顺序:
    true 的触发顺序总是在 false 之前;捕获(true)阶段的事件监听器会在任何非捕获(false)阶段的事件监听器之前被调用。
    如果多个均为 true,则外层的触发先于内层;
    如果多个均为 false,则内层的触发先于外层。
    注意,不适用于 IE。

    addEventListener-事件流,分为三个阶段

    捕获阶段: 从根节点开始顺序而下,检测每个节点是否注册了事件处理程序。如果注册了事件处理程序,并且 useCapture 为 true,则调用该事件处理程序。(IE 中无此阶段。)

    目标阶段: 触发在目标对象本身注册的事件处理程序,也称正常事件派发阶段。

    冒泡阶段: 从目标节点到根节点,检测每个节点是否注册了事件处理程序,如果注册了事件处理程序,并且 useCapture 为 false,则调用该事件处理程序。

    多个事件示例

    <button id="myBtn">Event</button>
    <script>
        var btn = document.getElementById("myBtn");
            btn.addEventListener("click", function () {
                alert(this.id);
            }, false);
            btn.addEventListener("click", function () {
                alert("Hello World");
            }, false);
    </script>
    var btn = document.getElementById("myBtn");
    //通过addEventListener()添加的匿名函数无法移除
    btn.addEventListener("click", function () {
        alert(this.id);
    }, false);
    btn.removeEventListener("click", function () {  //无效!
        alert(this.id);
    }, false);
    //removeEventListener无法删除addEventListener所追加的事件,因为两个方法(匿名)并不相等,内存地址已经是不同的
    var handler = function () {
            alert(this.id);
    btn.addEventListener("click", handler, false);
    btn.removeEventListener("click", handler, false);  //有效!

    一旦事件绑定之后,该绑定代码作用域的变量就都保留下来,不会被 JavaScript 引擎回收,这可能会引起占用大量内存的问题,由于 removeEventListener 无法删除匿名函数的事件处理程序,只有在物件(比如按钮)去除之后,该内存才可能得到回收。 注意:内存地址十分的重要,一定要相同才可以删除

    dispatchEvent

    EventTarget 的 dispatchEvent() 方法会向一个指定的事件目标派发一个 Event,并以合适的顺序(同步地)调用所有受影响的 EventListener。标准事件处理规则(包括事件捕获和可选的冒泡过程)同样适用于通过手动使用 dispatchEvent() 方法派发的事件。

    和经由浏览器触发,并通过事件循环异步调用事件处理程序的“原生”事件不同,dispatchEvent() 会同步调用事件处理函数。在 dispatchEvent() 返回之前,所有监听该事件的事件处理程序将在代码继续前执行并返回。

    注意: 在调用此方法时,Event.target 属性默认为当前的 EventTarget。

    使用代码来生成事件的步骤:首先用Event 构造函数创建一个新的 Event 对象。然后,使用 dispatchEvent() 方法触发事件。

    Event 构造函数

    文档地址: Event() 构造函数

    语法: let event = new Event(type, [,options]);

    返回值:无(undefined)

    type :指定事件类型,比如click。
    options 可选:为对象类型,有两个属性
    bubbles:Boolean类型,表示事件是否冒泡。默认值 false,如果为true,则事件冒泡,反之亦然。
    cancelable:Boolean类型,表示事件是否能取消。默认值 false,如果为true,则能取消,反之亦然。
    composed:Boolean类型,默认值为 false,指示事件是否会在影子 DOM 根节点之外触发侦听器。

    创建了一个点击事件: let clickEvent = new Event('click');

    dispatchEvent 使用

    创建完事件后,我们就可以使用dispatchEvent()。方法在目标元素上触发它: element.dispatchEvent(event);

    <script> window.onload = function (){ var myDiv=document.getElementById('myDiv' ) // 页面加载完成直接触发 myDiv.addEventListener('click', function () { alert( '点击了' ); let clickEvent = new Event('click' ); myDiv.dispatchEvent(clickEvent); </script> <div id="myDiv" style="width: 100px;height:100px;border:1px #ccc solid"></div> </body>

    区分事件是由用户触发还是代码触发 :event.isTrusted 属性为 true。如果事件由代码触发,则 event.isTrusted 为 false。

    Event 接口表示在 DOM 中出现的事件。有许多不同类型的事件,其中一些使用基于 Event 主接口的二次接口, 点击查看Event 接口列表 。例如 MouseEvent、TouchEvent、FocusEvent 和 KeyboardEvent。我们最好使用 例如 MouseEvent 这样的详细事件构造函数,而不是通用的 Event 构造函数,因为这些构造函数提供了更多特定于事件的信息。

    当有很多嵌套的元素,并且每一个元素都有着自己的事件处理函数,事件处理过程会变得非常复杂。尤其当一个父元素和子元素绑定有相同类型的事件处理函数的时候。因为结构上的重叠,事件处理函数可能会依次被触发,触发的顺序取决于事件冒泡和事件捕获在每一个元素上的设置情况。

    //指定事件发生时相对于视口的水平和垂直坐标
    let clickEvent = new MouseEvent("click", {
      bubbles: true,
      cancelable: true,
      clientX: 150,
      clientY: 150
    

    removeEventListener

    EventTarget 的 removeEventListener() 方法可以删除使用 EventTarget.addEventListener() 方法添加的事件。IE9 以下用 detachEvent()  代替。

  • removeEventListener(type, listener);
  • removeEventListener(type, listener, options);
  • removeEventListener(type, listener, useCapture);
  • 返回值:无(undefined)

    type:字符串,表示需要移除的事件类型。
    listener:需要从目标事件移除的事件监听器函数。
    options 可选:指定事件侦听器特征的可选对象。可选项有:
      capture: 布尔值类型,默认值为 false。指定需要移除的事件监听器函数是否为捕获监听器。
      passive 可选:布尔值,默认值为 false。设置为 true 时,表示 listener 永远不会调用 preventDefault()。如果 listener 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告。
    useCapture 可选:布尔值,默认值为 false。指定需要移除的事件监听器函数是否为捕获监听器。true - 在捕获阶段移除事件句柄,false - 在冒泡阶段移除事件句柄。

    注意: 如果添加两次事件,一次在捕获阶段,一次在冒泡阶段,你必须单独移除该事件。

    移除时传入的参数与添加处理程序时使用的参数必须相同

    <button id="myBtn">Event</button>
    <script>
        var btn = document.getElementById("myBtn");
            btn.addEventListener("click",clickFn,false);
            function  clickFn() {
                alert(this.id);
                // option.passive 不同不影响结果,option.capture 与 useCapture 不同影响是否成功
                // btn.removeEventListener("click",clickFn ,{ passive: true, capture: true }, false);// 失败
                // btn.removeEventListener("click",clickFn ,{ passive: true }, false);// 成功
                // btn.removeEventListener("click",clickFn ,{ passive: true }) // 成功
                // btn.removeEventListener("click",clickFn , true); // 失败
                // btn.removeEventListener("click",clickFn , false); // 成功
    </script>

    还有一种移除事件监听器的方法:可以向 addEventListener() 传入一个 AbortSignal,稍后再调用拥有该事件的控制器上的 abort() 方法即可。

    相关文章:

    MDN 介绍

    addEventListener 用法

    dispatchEvent() 代码触发事件

    addEventListener()与removeEventListener(),追加事件和删除追加事件