善用事件代理,警惕闭包的性能陷阱。

简言之,闭包是产生一个没有被释放资源的栈区。换言之,就是一个不可控的内存空间占用,如果与事件相关联,JS的垃圾回收机制也不会去触碰该区域。
例如:我们有个项目需要实现在一个div中有上百个热点区域(a标签),类似淘宝店铺广告位自定义,那么按照传统的做法,我们会如下做一个最典型的闭包使用的实例,目的是改变this的作用域,在其处理函数内部调用其他属于该作用域的方法或属性。


代码如下:

var apply = function() {
  this.div = document.getElementById("div的id");
  this.hot = this.div.getElementsByTagName("a");
  for(var i=0; i<this.hot.length; i++) {
    this.hot[i].onclick = function(me) {
      return function() {
        me.edit(this);
      }
    }(this);
  }
}
apply.prototype = {
  edit: function(target) {
  }
}

这里产生的问题,就是每一次的循环,都会往内存当中写入一个如上所描述的不可控的内存地址,当然,你找不到它,也没办法在不需要使用的时候清理它,js的回收机制也不知道他何时是无用的,产生垃圾地址。并且,当div内的dom结构发生改变的时候,你又需要重新去找到这些a标签然后给他绑定事件。
当然你也可以把this添加到一个局部变量:var me = this; 至少如此是你可以控制的,你可以随时的将局部变量me置为null,js的垃圾回收机制会知道何时去清理掉这些无用的数据。但是这样也不是最好的解决方案,并且估计很多人也不会喜欢这种并不美观的编码方式。
最好的解决办法,当然还是并不需要去关心那些内部的结构,也不为内部的任何一个元素申明任何一个变量,那么就是事件代理的工作。何谓事件代理,即不需要为每一个子对象绑定事件,通过冒泡机制找到当前触发事件的元素,并通过你自己的一系列规则找到最终的处理函数。
如果使用事件代理的模式,该如何实现如上描述的需求?如下:


代码如下:

var apply = function() {
  this.div = document.getElementById("div的id");
  this.div.onclick = function(me) {
    return function() {
      var _event = arguments.callee.caller.arguments[0];
      var target = _event.target || _event.srcElement;
      if(target.tagName == "a")
        me.edit(target);
      else
        return false;
    }
  }(this);
}
apply.prototype = {
  edit: function(target) {
  }
}

现在,我们只关心容器元素是何物,而不用关心他的内部有多少个a,他们是否发生改变等。性能的差别是显然的。
10来分钟随便写写,有点混乱,希望对一些朋友有用,如有差错之处,还望各位指点。

auntion / 2011-11-15
mail Auntion@gmail.com
QQ 82874972
原创文章,转载请留下此部分信息

(0)

相关推荐

  • javascript 自定义事件初探

    还有,"通过事件机制,可以将类设计为独立的模块,通过事件对外通信,提高了程序的开发效率.".相信C#程序员对事件的好处是深有体会的.好了,Code is cheap.看代码: function class1() { // 最简单的事件设计模式 } class1.prototype = { show: function () { this .onShow(); }, onShow: function () { } } function test() { var obj = new cla

  • javascript中的事件代理初探

    事件在javascript中一直是最强大的对象之一.javascript提供了addEventListener和attachEvent两个方法来为DOM节点绑定事件,jquery作了进一步封装,提供了兼容各个浏览器的bind方法.现在来看,这种传统的事件绑定方式存在着以下不足: 1.可能需要绑定很多的EventHander. 假如页面中某个表有100行,现在必须为每一行绑定一个click事件.那么就必须绑定100个EventHandler,这对页面性能来说有着极大的负担,因为需要创建更多的内存来

  • 善用事件代理,警惕闭包的性能陷阱。

    简言之,闭包是产生一个没有被释放资源的栈区.换言之,就是一个不可控的内存空间占用,如果与事件相关联,JS的垃圾回收机制也不会去触碰该区域. 例如:我们有个项目需要实现在一个div中有上百个热点区域(a标签),类似淘宝店铺广告位自定义,那么按照传统的做法,我们会如下做一个最典型的闭包使用的实例,目的是改变this的作用域,在其处理函数内部调用其他属于该作用域的方法或属性. 复制代码 代码如下: var apply = function() { this.div = document.getElem

  • 深入分析Javascript事件代理

    很久很久以来,总感觉事件发生与事件代理到之间没什么鸟区别. 最近,又看了一下,感觉区别其实真不大!看怎么理解吧. 要搞清楚什么是事件代理,就需要先搞清楚什么是代理. 从商业角度来讲,代理就是:我有货,你没货,但丫我没时间.没精力全部卖掉,而你一天闲的蛋疼,只剩下时间了.于是,我委托你帮我买,然后哥给你提成.这个过程中,你实际上相当于也有了货. OK,怎么从字面来理解事件代理一词的含义?后文有讲. 一 先看一个真实的,新手绑定onclik事件的例子 如果按照之前的我,我会怎么给每一个li标签,添加

  • js中的事件委托或是事件代理使用详解

    起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它还有一个名字叫事件代理,JavaScript高级程序设计上讲:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件.那这是什么意思呢?网上的各位大牛们讲事件委托基本上都用了同一个例子,就是取快递来解释这个现象,我仔细揣摩了一下,这个例子还真是恰当,我就不去想别的例子来解释了

  • 详解js的事件代理(委托)

    JavaScript事件代理(委托)一般用于以下情况: 1. 事件注册在祖先级元素上,代理其子级元素.可以减少事件注册数量,节约内存开销,提高性能. 2. 对js动态添加的子元素可自动绑定事件. 之前一直用各种js库的事件代理,如 jQuery,非常方便实用.今天尝试用原生 js 实现该功能. var addEvent = (function () { if (document.addEventListener) { return function (element, type, handler

  • 浅析javascript中的事件代理

    本文的主要内容是根据前不久面试某家公司Web前端开发岗位,面试时做的一道数组去重问题的解题思路进行整理的,分享给大家. 题目本身很简单:一个ul中有一千个li,如何给这一千个li绑定一个鼠标点击事件,当鼠标点击时alert出这个li的内容和li的位置坐标xy, <ul id="ulItem"> <li id="li1">1</li> <li id="li2">2</li> <li

  • js事件委托和事件代理案例分享

    什么是事件委托/事件代理 利用事件的冒泡传播机制(触发当前元素的某一个行为,它父级所有元素的相关行为都会被触发),如果一个容器中有很多元素都要绑定点击事件,我们没有必要一个个的绑定了,只需要给最外层容器绑定一个点击事件即可,在这个方法执行的时候,通过事件源的区分来进行不同的操作. 具体小案例如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

  • JavaScript的事件代理和委托实例分析

    在JavaScript中,经常会碰到要监听列表中多项li的情形,假设我们有一个列表如下: 复制代码 代码如下: <ul id="list">   <li id="item1">item1</li>   <li id="item2">item2</li>   <li id="item3">item3</li>   <li id="

  • JavaScript事件代理和委托详解

    在javasript中,代理.委托经常出现. 那么它究竟在什么样的情况下使用?它的原理又是什么? 这里介绍一下javascript delegate的用法和原理,以及Dojo,jQuery等框架中delegate的接口. JavaScript事件代理 事件代理在JS世界中一个非常有用也很有趣的功能.当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数. 这主要得益于浏览器的事件冒泡机制,下面我们具体举个例子来解释如何使用这个特性. 这个例子主要取

  • JavaScript通过事件代理高亮显示表格行的方法

    本文实例讲述了JavaScript通过事件代理高亮显示表格行的方法.分享给大家供大家参考.具体实现方法如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Highlight Rows</title> <style type

随机推荐