• 事件绑定/委托


    首先要做的第一件事情就是要先搞清楚什么是事件委托/绑定,这个东西有什么用,有什么优点和缺点,这样才能更好的去了解学习相关的知识。

    那就先做第一件事,认识事件绑定,不过说这个之前得先了解一下DOM事件流。

    1、什么是事件流

    事件流描述的是从页面中接收事件的顺序。但有意思的是,IE 和 Netscape 开发团队居然提出了差
    不多是完全相反的事件流的概念。IE 的事件流是事件冒泡流,而 Netscape Communicator 的事件流是事
    件捕获流。

    a、IE中的事件流

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

    如果你单击了页面中的 <div> 元素,那么这个 click 事件会按照如下顺序传播:
    (1) <div>
    (2) <body>
    (3) <html>
    (4) document

    代码如下:

    1 <!DOCTYPE html>
    2 <html>
    3 <head>
    4 <title>Event Bubbling Example</title>
    5 </head>
    6 <body>
    7 <div id="myDiv">Click Me</div>
    8 </body>
    9 </html>

    b、Netscape提出的事件流

    Netscape Communicator团队提出的另一种事件流叫做事件捕获(event capturing)。事件捕获的思想
    是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于在
    事件到达预定目标之前捕获它。

    如果仍以前面的 HTML 页面作为演示事件捕获的例子,那么单击 <div>元素就会以下列顺序触发 click 事件。

    (1)  document

    (2) <html>
    (3) <body>
    (4) <div>

    “DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首
    先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件。最后一个阶段是冒泡阶
    段,可以在这个阶段对事件做出响应。

    再贴一个很形象的图片:

     2、事件处理程序

    a、HTML事件处理程序

    某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的 HTML 特性来指定。

    b、 DOM0 级事件处理程序

    通过 JavaScript 指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性

    c、DOM2 级事件处理程序

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

     

    3、什么是事件委托/绑定

    对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了事件冒泡,只指定一个事
    件处理程序,就可以管理某一类型的所有事件。例如, click 事件会一直冒泡到 document 层次。也就
    是说,我们可以为整个页面指定一个 onclick 事件处理程序,而不必给每个可单击的元素分别添加事
    件处理程序。

    那事件委托有什么用呢?

    //1.事件未绑定第一个问题 事件覆盖问题
    //没有加事件绑定时出现的问题

     <div style="height:100px; 100px; background="red"; ">测试</div>
    1
    var box = document.getElementsByTagName('div')[0]; 2 box.onclick = function() { 3 alert(1); 4 }; 5 box.onclick = function() { 6 alert(2); 7 }; 8 box.onclick = function() { 9 alert(3); // 只有这一个会显示 前两个都会被覆盖掉 10 };

    //有加事件绑定时

    1 box.addEventListener("click", function() {
    2         alert(1) //这里的每一个都会显示出来
    3     }, false)
    4     box.addEventListener("click", function() {
    5         alert(2) //这里的每一个都会显示出来
    6     }, false)
    7     box.addEventListener("click", function() {
    8         alert(3) //这里的每一个都会显示出来
    9     }, false)

    //2.事件绑定第二个问题    相同函数屏蔽问题

    1 box.addEventListener("click",fn, false)
    2     box.addEventListener("click",fn, false)
    3     function fn(){
    4         alert(1)
    5     }

    //3.事件绑定第三个问题 传递this问题
    //没有事件绑定时的this

     1 box.onclick = function() {
     2         fn();
     3     };
     4 
     5     function fn() {
     6         alert(this); //window  这里的this指的还是window
     7     };
     8 
     9     //有事件绑定时的this
    10     box.addEventListener('click', fn, false);
    11 
    12     function fn() {
    13         alert(this); //div   this的值从上面传过来了
    14     };

    //4.事件绑定第三个问题      添加一个事件会被覆盖或者只执行一次

     1 box.onclick = function() {
     2         alert(100);
     3     };
     4     box.onclick = fn;
     5 
     6     function fn() {
     7         alert(200);
     8     };
     9 
    10     box.addEventListener("click", function() {
    11         alert(100);
    12     }, false)
    13     box.addEventListener("click", fn, false)
    14 
    15     function fn() {
    16         alert(200);
    17     };

    //IE中 event对象的获取

    1 box.onclick=function(ev){
    2         alert(ev)  //传统方法IE无法通过参数获取ev
    3     }
    4     box.addEventListener("click",function(ev){
    5         alert(ev)   //可以通过事件绑定来获取
    6     })

    最后就是兼容封装

     1 //兼容写法封装
     2     //添加事件绑定
     3     function addEvent(obj, event, fn, bool) { //obj对象  event:事件  fn绑定函数  bool:是否捕获
     4         if (obj.addEventListener) {
     5             obj.addEventListener(event, fn, bool);
     6         } else {
     7             obj.attachEvent('on' + event, fn)
     8         }
     9     }
    10 
    11     //删除事件绑定
    12     function removeEvent(obj, event, fn, bool) { //obj对象  event:事件  fn绑定函数
    13         if (obj.removeEventListener) {
    14             obj.removeEventListener(event, fn, bool);
    15         } else {
    16             obj.detachEvent('on' + event, fn)
    17         }
    18     }
    window.onload = function(){
      var oUl = document.getElementById("ul1");
      oUl.onclick = function(ev){
        var ev = ev || window.event;  //event兼容写法
        var target = ev.target || ev.srcElement;  //target兼容写法
        if(target.nodeName.toLowerCase() == 'li'){
             alert(target.innerHTML);
        }
      }
    }

     

    更加详细的去参考高级程序设计第13章

     

    事件流

    事件流

  • 相关阅读:
    Uva 11401 数三角形
    Uva 11538 象棋中的皇后
    数学基础——基本计数方法
    八数码问题
    python 爬poj.org的题目
    python 爬图片
    hiho 第135周 九宫
    Uva 11464 偶数矩阵
    BZOJ 1001 [BeiJing2006]狼抓兔子
    LA 3708 墓地雕塑
  • 原文地址:https://www.cnblogs.com/colaman/p/6204329.html
Copyright © 2020-2023  润新知