zoukankan      html  css  js  c++  java
  • javascript事件委托event delegation

    Web应用都是由事件驱动运转的。我喜欢事件处理,尤其喜欢自己定义事件。
    它能使你的产品可扩展,而不用改动核心代码。
    有一个很大的问题(也可以说是功能强大的表现),是关于页面上事件的移除问题。你可以对某个元素安装一个事件监听器,事件监听器就开始运转工作。
    但页面上没有任何指示说明这有个监听器。因为这种不可表现的问题 (这尤其让一些新手头疼) ,以及像IE6这样的”浏览器“在太多的使用事件监听时会出现各种的内存问题,你不得不承认尽量少使用事件编程是个明智的做法。

    于是 事件委托 就出现了。
    当页面上某个元素上的事件触发时,而在 DOM 继承关系上,这个元素的所有子元素也能接收到这个事件,这时你可以使用一个在父元素上的事件处理器来处理,而不是使用一堆的各个子元素上的事件监听器来处理。

    究竟是什么意思?这样说吧,页面上有很多超链接,你不想直接使用这些链接,想通过一个函数来调用这个链接,

    <h2>Great Web resources</h2>
    <ul id="resources">
      <li><a href="http://opera.com/wsc">Opera Web Standards Curriculum</a></li>
      <li><a href="http://sitepoint.com">Sitepoint</a></li>
      <li><a href="http://alistapart.com">A List Apart</a></li>
      <li><a href="http://yuiblog.com">YUI Blog</a></li>
      <li><a href="http://blameitonthevoices.com">Blame it on the voices</a></li>
      <li><a href="http://oddlyspecific.com">Oddly specific</a></li>
    </ul>

    The normal way to apply event handlers here would be to loop through the links:

    // Classic event handling example
    (function(){
      var resources = document.getElementById('resources');
      var links = resources.getElementsByTagName('a');
      var all = links.length;
      for(var i=0;i<all;i++){
        // Attach a listener to each link
        links[i].addEventListener('click',handler,false);
      };
      function handler(e){
        var x = e.target; // Get the link that was clicked
        alert(x);
        e.preventDefault();
      };
    })();

    This could also be done with a single event handler:

    (function(){
      var resources = document.getElementById('resources');
      resources.addEventListener('click',handler,false);
      function handler(e){
        var x = e.target; // get the link tha
        if(x.nodeName.toLowerCase() === 'a'){
          alert('Event delegation:' + x);
          e.preventDefault();
        }
      };
    })();

    Because the click happens on all the elements in the list, all you need to do is compare the nodeName to the right element that you want to react to the event.

    The benefits of this approach are more than just being able to use a single event handler. Say, for example, you want to add more links dynamically to this list. With event delegation, there is no need to change anything; with simple event handling, you would have to reassign handlers and re-loop the list.

     

    这个原理就是通过冒泡实现事件委托

    事件委托的关键就是在通过冒泡方式实现在最高层(通常是document)处理事件。不是所有的事件都支持冒泡,但是鼠标和键盘事件支持,并且这也是你所关心的。回顾下前面的例子,你可以通过在document上分配一个事件来处理所有的单击事件,只需要通过区别节点来决定处理事件的方法。
    使用事件委托,数个事件处理函数可以使用一个函数来管理。所有的单击事件被委托给一个合适的函数来处理。同样,mousedownmouseupmousemovemouseovermouseoutdblclickkeyupkeydown,  和keypress事件也可以这样处理。但是,在事件委托中mouseover和mouseout的处理方法是不同的,当鼠标从一个元素移动到它的子元素内的时候,被认为是"out"。
     
    注意:你也可以使用事件捕获来完成事件委托,但这只能用在支持事件捕获的非IE浏览器中。
     
    优点
    事件委托对于web应用程序的性能有如下几个优点:
    1.需要管理的函数变少了
    2.占用的内存少了
    3.javascript代码和Dom结构之间的关联更少了
    4.在改变DOM结构中的innerHTML时,不需要改动事件处理函数
     
    从传统的事件处理方法转向事件委托提高了大型web应用的性能。正因为它如此的重要,一些类似于YUI、jQuey的javascript库也开始将事件委托应用在它们的核心接口中。实现事件委托是很轻松的,却能带来性能上很大的提高。尤其表现在你将数十个事件处理函数整合到一个函数里。试一下事件委托,你就不会再使用传统的事件处理方法了。

    via:http://coding.smashingmagazine.com/2010/04/20/seven-javascript-things-i-wish-i-knew-much-earlier-in-my-career/

     

  • 相关阅读:
    常用集合比较
    windows和centos下安装ActiveMQ
    windows + maven + eclipse
    Eclipse常用插件 + Eclipse快捷键
    Zookeeper + Dubbo + SpringMVC + dubbo-admin
    Hession集成Spring + maven依赖通讯comm项目 + 解决@ResponseBody中文乱码
    Spring结合log4j(slf4j)
    nginx安装配置+集群tomcat:Centos和windows环境
    Manthan, Codefest 18 (rated, Div. 1 + Div. 2) ABCDE
    51nod 1483 化学变化
  • 原文地址:https://www.cnblogs.com/youxin/p/2736981.html
Copyright © 2011-2022 走看看