javascript中的事件代理初探

事件在javascript中一直是最强大的对象之一。javascript提供了addEventListener和attachEvent两个方法来为DOM节点绑定事件,jquery作了进一步封装,提供了兼容各个浏览器的bind方法。现在来看,这种传统的事件绑定方式存在着以下不足:

1.可能需要绑定很多的EventHander。

假如页面中某个表有100行,现在必须为每一行绑定一个click事件。那么就必须绑定100个EventHandler,这对页面性能来说有着极大的负担,因为需要创建更多的内存来存放这些Handler。

2.事件无法绑定后加入的DOM节点。

假如页面中的代码如下:


代码如下:

$("#dv").bind('click',function(){alert('test');});
$(body).append('<div id="dv">test</div>')

后加入的div是无法触发点击事件的。

为了解决这两个问题,javascript引入了事件代理(event proxy)。首先,我们了解一下js中的冒泡机制。

基本上所有的浏览器都支持事件冒泡。当在某个DOM节点上触发事件上,事件会一直向上传递,一直到文档的根节点。既然所有的节点的事件最终都会传递到文档根节点,那么我们如果直接将事件绑定到文档根节点(document节点),然后通过event.target来判断是哪个节点触发的事件,是不是减少很多EventHandler的绑定呢?

jquery中的live方法正式根据这个原理来实现的,下面我们来实现一个live简单版:


代码如下:

$.fn.mylive=function(eventType,fn){
 var that=this.selector;
 $(document).bind(eventType,function(event){
  var match=$(event.target).closest(that)
  if(match.length !== 0){
   fn.apply($(event.target),[event]);
  }
 })
}

$("#tb td").mylive('click',function(event){
 alert(event.target.innerHTML);
});

var tb='<table id="tb"> \
  <tr> \
   <td>the first column</td>\
   <td>the second column</td>\
   <td>the third column</td>\
  </tr>\
</table>';
$("body").append(tb);

live方法中,事件绑定在document节点上,$(event.target).closest(that)来匹配真正触发事件的元素。demo中,我们为每个后加入的td都绑定了click事件,单击不同的td,我们发现会弹出他们对应Text的提示框。

live方法弥补了前面提到的传统事件绑定方法的两个不足。但live方法仍存在它的不足之处。看这句代码:


代码如下:

$("#tb td").mylive('click',function(event){
 alert(event.target.innerHTML);
});

它会首先根据jquery选择器遍历整个文档,找到所有的#tb td元素,将他们存储成对象。然而,在live的实现方法中,并没有利用这些对象,而仅仅是将"#td td"作为字符串与事件源进行匹配而已。这就大大增加了很多无谓的消耗。

那么有没有办法改善这一状况呢?jquery中提供了delegate代理方法,它支持将事件绑定到指定的元素上,而不仅仅是document上。了解了它的原理,我们来实现一个delegate简单版:


代码如下:

$(body).append('<div id="dv"></div>');

$.fn.mydelegate=function(selector,eventType,fn){
 $(this).bind(eventType,function(event){
  var match=$(event.target).closest(selector);
  if(match.length !== 0){
   fn.apply($(event.target),[event]);
  }
 });
}

$("#dv").mydelegate('td','click',function(event){
 alert(event.target.innerHTML);
});

var tb='<table id="tb"> \
  <tr> \
   <td>the first column</td>\
   <td>the second column</td>\
   <td>the third column</td>\
  </tr>\
</table>';
$("dv").append(tb);

mydeletage方法不需要获取所有的td对象,而仅仅只需要获取绑定事件的div对象。这在执行效率上要优于live方法。

这里仅仅起到一个抛砖引玉的作用,让大家了解到事件代理的原理而已,jquery中的live和delegate实现要复杂的多。

时间: 2014-03-06

javascript性能优化之事件委托实例详解

本文实例分析了javascript性能优化之事件委托.分享给大家供大家参考,具体如下: 为下面每个LI绑定一个click事件 <ul id="myLinks"> <li id="goSomewhere" >Go somewhere</li> <li id="doSomething" >Do something</li> <li id="sayHi" >Sa

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世界中一个非常有用也很有趣的功能.当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数. 这主要得益于浏览器的事件冒泡机制,下面我们具体举个例子来解释如何使用这个特性. 这个例子主要取

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

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

JS 事件绑定、事件监听、事件委托详细介绍

在JavaScript的学习中,我们经常会遇到JavaScript的事件机制,例如,事件绑定.事件监听.事件委托(事件代理)等.这些名词是什么意思呢,有什么作用呢? 事件绑定 要想让 JavaScript 对用户的操作作出响应,首先要对 DOM 元素绑定事件处理函数.所谓事件处理函数,就是处理用户操作的函数,不同的操作对应不同的名称. 在JavaScript中,有三种常用的绑定事件的方法: 在DOM元素中直接绑定: 在JavaScript代码中绑定: 绑定事件监听函数. 在DOM中直接绑定事件

JavaScript事件委托用法分析

本文实例讲述了JavaScript事件委托用法.分享给大家供大家参考.具体分析如下: 一.点击页面任何部分触发事件 创建一个script1.js文件. 复制代码 代码如下: (function() {     eventUtility.addEvent(document, "click", function(evt) {         alert('hello');     }); }()); 页面部分. 复制代码 代码如下: <head> <meta http-e

JavaScript事件委托技术实例分析

本文实例分析了JavaScript事件委托技术.分享给大家供大家参考.具体分析如下: 如果一个整体页面里有大量的按钮.我们就要为每一个按钮绑定事件处理程序.这样就会影响性能了. 首先每个函数都是对象,对象就会占用很多内存.内存中的对象越多,性能就越差. 其次,dom访问次数增多,就会导致延迟加载页面.事实上,从如何来利用好事件处理程序,还是有很好的解决方案的. 事件委托: 对事件处理程序过多的问题解决的方案就是事件委托技术. 事件委托技术利用了事件冒泡.只需指定一个事件处理程序. 我们可以为某个

JavaScript事件委托的技术原理探讨示例

如今的JavaScript技术界里最火热的一项技术应该是'事件委托(event delegation)'了.使用事件委托技术能让你避免对特定的每个节点添加事件监听器:相反,事件监听器是被添加到它们的父元素上.事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件.基本概念非常简单,但仍有很多人不理解事件委托的工作原理.这里我将要解释事件委托是如何工作的,并提供几个纯JavaScript的基本事件委托的例子. 假定我们有一个UL元素,它有几个子元素: 复制代码 代码如下: <ul id=&qu

JavaScript中的事件委托及好处

1,什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件. 也就是:利用冒泡的原理,把事件加到父级上,触发执行效果. 好处呢:1,提高性能. 我们可以看一个例子:需要触发每个li来改变他们的背景颜色. <ul id="ul"> <li>aaaaaaaa</li> <li>bbbbbbbb&l

javascript事件委托的方式绑定详解

js事件绑定 事件绑定,这里使用了冒泡的原理,从点击的元素开始,递归方式的向父元素传播事件,这样做的好处是对于大量要处理的元素,不必为每个元素都绑定事件,只需要在他们的父元素上绑定一次即可,提高性能.还有一个好处就是可以处理动态插入dom中的元素,直接绑定的方式是不行的. 之前一直使用的是jquery的on方法做这样的事情,前几天看到公司项目中有实现这种方式的源代码,拿来仔细研究研究,跟大家分享分享. function $bindAction(dom, event, listeners) { #

java实现事件委托模式的实例详解

java实现事件委托模式的实例详解 举例说明: 一个班级,有两类学生,A类:不学习,玩,但是玩的东西不一样,有的是做游戏,与的是看电视(有点不合理) B类:放哨的学生,专门看老师的动向,如果老师进班了就立即通知大家. 如此就形成了一个需求,放哨的学生要通知所有玩的学生:老师来了,而不同的学生有不同的反应,有的马上把电视关闭,有的停止玩游戏. 设计的要求如下,让A类学生和B类学生完全解耦,即A类完全不知道B类的学生,却可以通知B类的学生. 代码及说明如下: Event 类,定义了一个事件类: pa

vue实现绑定事件的方法实例代码详解

一.前言 vuejs中的事件绑定,使用<v-on:事件名 = 函数名>来完成的,这里函数名是定义在Vue实例中的methods对象中的,Vue实例可以直接访问其中的方法. 二.事件绑定方式 1. 直接在标签中写js方法  <button v-on:click="alert('hi')">执行方法的第一种写法</button> 2.调用method的办法 <button v-on:click="run()">执行方法的第

基于javascript的拖拽类封装详解

效果图如下 github地址如下: github地址 使用方法 引入js和对应的css import Drag from '../../static/dragger.js' import './assets/css/dragger.css' 之后,实例化 new Drag({ id: 'box-dragger', showAngle: true, isScale: false, showBorder: false }) new Drag({ id: 'box-dragger2', canZoom

Javascript类型系统之String字符串类型详解

javascript没有表示单个字符的字符型,只有字符串String类型,字符型相当于仅包含一个字符的字符串 字符串String是javascript基本数据类型,同时javascript也支持String对象,它是一个原始值的包装对象.在需要时,javascript会自动在原始形式和对象形式之间转换.本文将介绍字符串String原始类型及String包装对象 定义 字符串String类型是由引号括起来的一组由16位Unicode字符组成的字符序列 字符串类型常被用于表示文本数据,此时字符串中的

JavaScript中浅讲ajax图文详解

1.ajax入门案例 1.1 搭建Web环境 ajax对于各位来说,应该都不陌生,正因为ajax的产生,导致前台页面和服务器之间的数据传输变得非常容易,同时还可以实现页面的局部刷新.通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新. 对于JavaWeb项目而言,ajax主要用于浏览器和服务器之间数据的传输. 如果是单单地堆砌知识点,会显得比较无聊,那么根据惯例,我先不继续介绍ajax,而是来写一个案例吧. 打开

bootstrap paginator分页插件的两种使用方式实例详解

分页有两种方式: 1. 前台分页:ajax一次请求获取全部数据,适合少量数据(万条数据以下): $.ajax({ type: "GET", url: "",//后台接口地址 dataType: "json", success: function (msg) { var pages = Math.ceil(msg.data / 5);//data是数据总量 var element = $('#id');//对应ul的id element.boots

java 实现websocket的两种方式实例详解

一.介绍 1.两种方式,一种使用tomcat的websocket实现,一种使用spring的websocket 2.tomcat的方式需要tomcat 7.x,JEE7的支持. 3.spring与websocket整合需要spring 4.x,并且使用了socketjs,对不支持websocket的浏览器可以模拟websocket使用 二.方式一:tomcat 使用这种方式无需别的任何配置,只需服务端一个处理类, 服务器端代码 package com.Socket; import java.io

JavaScript代码异常监控实现过程详解

这篇文章主要介绍了JavaScript代码异常监控实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 JavaScript异常一般有两方面:语法错误和运行时错误.两种错误的捕获和处理方式不同,从而影响具体的方案选型.通常来说,处理JS异常的方案有两种:try...catch捕获 和 window.onerror捕获.以下就两种方案分别分析各自的优劣. 虽然语法错误本应该在开发构建阶段使用测试工具避免,但难免会有马失前蹄部署到线上的时候.

JavaScript浏览器对象之一Window对象详解

JavaScript提供了一组以window为核心的对象,实现了对浏览器窗口的访问控制.JavaScript中定义了6种重要的对象: window对象 表示浏览器中打开的窗口: document对象 表示浏览器中加载页面的文档对象: location对象包含了浏览器当前的URL信息: navigation对象 包含了浏览器本身的信息: screen对象 包含了客户端屏幕及渲染能力的信息: history对象 包含了浏览器访问网页的历史信息. 除了window对象之外,其他的5个对象都是windo