zoukankan      html  css  js  c++  java
  • js的事件的三个阶段,事件委托的原理

    DOM2级事件规定的事件流的三个阶段:捕获,目标,冒泡(IE8以及更早版本不支持DOM事件流);

    事件流:
    IE:IE事件流是事件冒泡流  Netscape事件流是事件捕获流
    IE事件流 叫做事件冒泡,即事件开始时由最具体的元素(文档中嵌套最深的那个节点)接收,然后逐级向上(一直到文档)。事件捕获与事件冒泡事件流正好相反的顺序,事件捕获的事件流是最外层逐级向内传播。

    
    
    使用DOM0级方法指定的事件处理程序被认为是元素的方法,处理程序是在元素的作用域进行的,程序中this是引用的是当前元素
    
    
    btn
    var btn = document.getElementById_x_x_x("btn"); btn.onclick = function(){ alert(this.id); // 弹出btn }

      单击元素btn后,通过this.id取得元素的属性id,还可以通过this访问元素的任何属性和方法,以这种方式添加的事情处理程序在事件流的冒泡阶段处理。

      也可以删除通过DOM0级方法指定的事件处理程序,只要将事件处理程序的属性值设置为null即可。

      btn.onclick = null; // 删除事件处理程序;

     DOM2级事件处理程序

    事件是在冒泡阶段被触发,与DOM0级方法一样,这里添加的事件处理程序也是在其依副的元素作用域中运行,使用DOM2级添加事件处理程序的好处是可以添加多个事件处理程序,如下代码:

    var btn = document.getElementById_x_x_x("btn"); btn.addEventListener('click',function(e){ alert(this.id); },false); btn.addEventListener('click',function(e){ alert("我是来测试的"); },false);

      上面的代码被弹出2次对话框,而在DOM0级是不可以的;它永远是执行最后一次的。

    参考:http://www.admin10000.com/document/6293.html

     IE事件处理的程序

    btn.attachEvent('onclick',handler); function handler(e){ alert(this); // window }

      注意:attachEvent的事件名称是onclick,而addEventListener的事件名称是click,且IE中使用的attachEvent()与使用DOM0级方法的的主要区别在于事件处理程序的作用域,在使用dom0级情况下,事件处理程序在其所属元素的作用域内运行,在使用attachEvent()方法的情况下,事件处理程序在全局作用域下运行,其中的this等于window。

    理解标准浏览器下的事件对象与IE下的事件对象

     

      标准浏览器下的事件对象是event,比如btn点击后;如下代码:

    var btn = document.getElementById_x_x_x("btn"); btn.onclick = function(){ console.log(event); //标准浏览器下打印事件对象 console.log(event.type);//'click' } btn.onclick = function(){ // IE下打印的事件对象window.event console.log(window.event); console.log(window.event.type); // 'click' }

      上面的写法是在DOM0级上注册事件,如果我们在Dom2级上注册事件的话,那么就会有一个事件对象event作为参数传入事件到函数中,如下:

    var btn = document.getElementById_x_x_x("btn"); EventUtil.addHandler(btn,'click',function(e){ console.log(e); });

     理解特定事件的默认行为事件

    在标准浏览器下
    alink.onclick = function(e){ console.log(e) e.preventDefault(); }

       IE下

    alink.onclick = function(){ console.log(window.event) window.event.returnValue = false; }

    标准浏览器下与IE下的事件目标的区别

     console.log(event.target); // 打印事件目标元素 

     console.log(window.event.srcElement); 

    理解标准浏览器与IE下阻止事件传播的区别

     

      在标准浏览器下我们可以使用stopPropagation()方法来停止事件在DOM层次中的传播,即取消事件中的冒泡或者捕获。从而避免触发注册在document.body上面的事件处理程序

    标准浏览器e.stopPropagation()

    IE:window.event.cancelBubble = true

    跨浏览器的事件对象

     
    
    
    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;
             }
        },
       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.cancelBubble = true;
               }
        }
    };

    理解客户区坐标位置

     

      含义是:鼠标指针在可视区中的水平clientX和垂直clientY坐标;

      如下图所示:

      

    理解页面坐标位置pageX和pageY:

     

      pageX与pageY是指页面坐标的位置,与clientX和clientY的区别是:它包含页面滚动条的位置,如下图所示:

      

    但是IE8及更早的版本不支持pageX与pageY

    EventUtil.addHandler(btn,'click',function(e){ e = EventUtil.getEvent(e); var pageX = e.pageX, pageY = e.pageY; if(!pageX) { pageX = e.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft); } if(!pageY) { pageY = e.clientY + (document.body.scrollTop || document.documentElement.scrollTop); } console.log("页面X轴坐标为:"+pageX + " "+ "页面Y轴坐标为:"+pageY); });

     理解屏幕坐标的位置

      屏幕横坐标screenX和垂直坐标screenY属性是相对于整个屏幕的。如下图所示:

    Javascript事件委托的原理

    原理:使用事件委托技术能让你避免对特定的每个节点添加事件监听器;相反,事件监听器是被添加到它们的父元素上,利用冒泡的原理,把事件加到父级上,触发执行效果。

    eg:

    <</span>ul id="parent-list">
      <</span>li id="post-1">Item 1</</span>li>
      <</span>li id="post-2">Item 2</</span>li>
      <</span>li id="post-3">Item 3</</span>li>
      <</span>li id="post-4">Item 4</</span>li>
      <</span>li id="post-5">Item 5</</span>li>
      <</span>li id="post-6">Item 6</</span>li>
    </</span>ul>
    
    function getEventTarget(e) {
      e = e || window.event;
      return e.target || e.srcElement;
    }
    
    
    // 获取父节点,并为它添加一个click事件
    document.getElementById_x("parent-list").addEventListener("click",function(e) {
      // 检查事件源e.targe是否为Li
    
        var target = getEventTarget(e);
      if(target && target .nodeName.toUpperCase == "LI") {
    // 真正的处理过程在这里 console.log("List item ",e.target.id.replace("post-")," was clicked!"); } });
    
    

    优点


    通过上面的介绍,大家应该能够体会到使用事件委托对于web应用程序带来的几个优点:
    1.可以大量节省内存占用,减少事件注册。
    2.可以方便地动态添加和修改元素,不需要因为元素的改动而修改事件绑定。
    3.JavaScript和DOM节点之间的关联变少了,这样也就减少了因循环引用而带来的内存泄漏发生的概率。
    缺点:
    不是所有的事件都能冒泡的。blur、focus、load和unload不能像其它事件一样冒泡。事实上blur和focus可以用事件捕获而非事件冒泡的方法获得(在IE之外的其它浏览器中)。
    在管理鼠标事件的时候有些需要注意的地方。如果你的代码处理mousemove事件的话你遇上性能瓶颈的风险可就大了,因为mousemove事件触发非常频繁。而mouseout则因为其怪异的表现而变得很难用事件代理来管理。
    参考:http://www.cnblogs.com/silence516/archive/2009/09/03/delegateEvent.html
  • 相关阅读:
    Odoo13在Win10(专业版)中的配置
    我在博客园安家了
    2012笔记
    你给我好好发邮件行不行
    事务经典例子
    轻松实现SQL Server与Access、Excel数据表间的导入导出
    SQL大全
    小笔记
    性能优化
    程序中的异常和错误处理
  • 原文地址:https://www.cnblogs.com/myzy/p/5226985.html
Copyright © 2011-2022 走看看