zoukankan      html  css  js  c++  java
  • JavaScript事件流

     

    1.概述

    事件流:页面中接受事件的顺序。

    IE的事件流是事件冒泡流,而Netscape的事件流是事件捕获流。

     

    2、事件冒泡

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

    也就是说, click 事件首先在 <div> 元素上发生,而这个元素就是我们单击的元素。然后, click事件沿 DOM 树向上传播,在每一级节点上都会发生,直至传播到 document 对象。

    所有现代浏览器都支持事件冒泡,但在具体实现上还是有一些差别。IE5.5 及更早版本中的事件冒泡会跳过 <html> 元素(从 <body> 直接跳到 document )。IE9、Firefox、Chrome 和 Safari 则将事件一直冒泡到 window 对象

    3、事件捕获

      事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点最后接收到事件。

    虽然事件捕获是 Netscape Communicator 唯一支持的事件流模型,但 IE9、Safari、Chrome、Opera和 Firefox 目前也都支持这种事件流模型

    尽管“DOM2 级事件”规范要求事件应该从 document 对象开始传播,但这些浏览器都是从 window 对象开始捕获事件的

    IE9、Opera、Firefox、Chrome 和 Safari 都支持 DOM 事件流;IE8 及更早版本不支持 DOM 事件流

    4、事件处理程序

    (1)HTML事件处理程序

    <input type="button" value="Click Me" onclick="alert('Clicked')" />

    缺点:

     HTML 与 JavaScript 代码紧密耦合

    (2)DOM0级事件处理程序

    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
    alert("Clicked");
    };
    btn.onclick = null; //删除事件处理程序

     

    优点:跨浏览器的优势,所有现代浏览器所支。缺点:DOM0 级对每个事件只支持一个事件处理程序。


    (3)DOM2级事件处理程序

    “DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作: addEventListener()和 removeEventListener()

    所有 DOM 节点中都包含这两个方法,并且它们都接受 3 个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是 true ,表示在捕获阶段调用事件处理程序;如果是 false ,表示在冒泡阶段调用事件处理程序注意添加的事件类似为click,非onclick

    var btn = document.getElementById("myBtn");
    btn.addEventListener("click", function(){
    alert(this.id);
    }, false);

    优点:使用 DOM2 级方法添加事件处理程序的主要好处是可以添加多个事件处理程序

    var btn = document.getElementById("myBtn");
    btn.addEventListener("click", function(){
    alert(this.id);
    }, false);
    btn.addEventListener("click", function(){
    alert("Hello world!");
    }, false);

    这里为按钮添加了两个事件处理程序。这两个事件处理程序会按照添加它们的顺序触发,因此首先会显示元素的 ID,其次会显示 "Hello world!" 消息。

    通过 addEventListener() 添加的事件处理程序只能使用 removeEventListener() 来移除;移除时传入的参数与添加处理程序时使用的参数相同。

    这也意味着通过 addEventListener() 添加的匿名函数将无法移除

    var btn = document.getElementById("myBtn");
    btn.addEventListener("click", function(){
    alert(this.id);
    }, false);
    // 这里省略了其他代码
    btn.removeEventListener("click", function(){ // 没有用!
    alert(this.id);
    }, false);

    以上代码不行。应该修改为:

    var btn = document.getElementById("myBtn");
    var handler = function(){
    alert(this.id);
    };
    btn.addEventListener("click", handler, false);
    // 这里省略了其他代码
    btn.removeEventListener("click", handler, false); // 有效!

    IE9、Firefox、Safari、Chrome和 Opera 支持 DOM2 级事件处理程序。

    (4)IE事件处理程序

    IE 实现了与 DOM 中类似的两个方法: attachEvent() 和 detachEvent() 。这两个方法接受相同的两个参数:事件处理程序名称与事件处理程序函数。由于 IE8 及更早版本只支持事件冒泡,所以通过attachEvent() 添加的事件处理程序都会被添加到冒泡阶段。

    var btn = document.getElementById("myBtn");
    btn.attachEvent("onclick", function(){
    alert("Clicked");
    });

    注意, attachEvent() 的第一个参数是 "onclick" ,而非 DOM 的 addEventListener() 方法中的 "click"

    在 IE 中使用 attachEvent() 与使用 DOM0 级方法的主要区别在于事件处理程序的作用域。在使用 DOM0 级方法的情况下,事件处理程序会在其所属元素的作用域内运行;在使用 attachEvent() 方法的情况下,事件处理程序会在全局作用域中运行,因此 this 等于 window

    var btn = document.getElementById("myBtn");
    btn.attachEvent("onclick", function(){
    alert(this === window); //true
    });
    var btn = document.getElementById("myBtn");
    btn.attachEvent("onclick", function(){
    alert("Clicked");
    });
    btn.attachEvent("onclick", function(){
    alert("Hello world!");
    });

    这里调用了两次 attachEvent() ,为同一个按钮添加了两个不同的事件处理程序。不过,与 DOM方法不同的是,这些事件处理程序不是以添加它们的顺序执行,而是以相反的顺序被触发。单击这个例子中的按钮,首先看到的是 "Hello world!" ,然后才是 "Clicked" 。

    使用 attachEvent() 添加的事件可以通过 detachEvent() 来移除,条件是必须提供相同的参数。与 DOM 方法一样,这也意味着添加的匿名函数将不能被移除

    支持 IE 事件处理程序的浏览器有 IE 和 Opera

    5、跨浏览器的事件处理程序

    var EventUtil = {
    addHandler: function(element, type, handler){
    if (element.addEventListener){
    element.addEventListener(type, handler, false);
    } else if (element.attachEvent){
    element.attachEvent("on" + type, handler);
    } else {
    element["on" + type] = handler;
    }
    },
    removeHandler: function(element, type, handler){
    if (element.removeEventListener){
    element.removeEventListener(type, handler, false);
    } else if (element.detachEvent){
    element.detachEvent("on" + type, handler);
    } else {
    element["on" + type] = null;
    }
    }
    };

    addHandler() 和 removeHandler() 没有考虑到所有的浏览器问题,例如在 IE 中的作用域问题

    此外还要注意,DOM0 级对每个事件只支持一个事件处理程序

    6、更新2019.1.3 

    还有DOM3事件流。DOM3事件流添加了更多的方法。如keydown等。

  • 相关阅读:
    ES6新特性
    CSS Sprites (css精灵)
    标准盒子模型和IE盒子模型
    鼠标跟随运动效果
    git 命令大全
    JavaScript 原型链
    js基础---cookie存储
    html5新增标签
    css清除浮动的方法
    querySelectorAll与getElementsBy对比有什么不同
  • 原文地址:https://www.cnblogs.com/mengfangui/p/8435316.html
Copyright © 2011-2022 走看看