JS冒泡事件与处理

摘要:
JavaSciprt事件有两个重要特性:事件冒泡和目标元素。这个过程称为事件冒泡;此事件从原始元素冒泡到DOM树的顶部。AttachEvent()用于将事件处理程序附加到事件。);3} 45varoDiv=文档。按ID获取元素;6分区。attachEvent;7o分区。detachEvent;气泡事件演示和处理方法:1˂!事件冒泡的优点和缺点:1.需要创建并驻留在内存中的事件处理器更少。向这1000个单元格中添加事件处理程序将导致严重的性能问题,并可能导致内存泄漏甚至浏览器崩溃。

JavaSciprt事件中有两个很重要的特性:事件冒泡以及目标元素。

事件冒泡: 当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这 一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。

目标元素: 任何一个事件的目标元素都是最开始的那个元素,在我们的这个例子中也就是按钮,并且它在我们的元素对象中以属性的形 式出现。使用事件代理的话我们可以把事件处理器添加到一个元素上,等待一个事件从它的子级元素里冒泡上来,并且可以很方便地得知这个事件是从哪个元素开始 的。

事件的冒泡和捕获

捕获是从上级元素到下级元素,冒泡是从下级元素到上级元素.

在IE中,每个元素和window对象都有两个方法:attachEvent()和detachEvent()。attachEvent()用来给 一个事件附加事件处理函数。而detachEvent()用来将事件处理函数分离出来。用法:

1 var fnClick = function() {
2     alert(“Clicked!”);
3 }
4 
5 var oDiv = document.getElementById(“div1”);
6 oDiv.attachEvent(“onclick”, fnClick);
7 oDiv.detachEvent(“onclick”, fnClick);

冒泡事件演示和处理方法:

 1 <!DOCTYPE html>
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3     
 4     <head>
      <meta charset="UTF-8">
5 <title> 6 JavaScript事件冒泡处理 7 </title> 8 <meta name="keywords" content="JavaScript,事件冒泡,cancelBubble,stopPropagation" 9 /> 10 <script type="text/javascript"> 11 function doSomething(obj, evt) { 12 alert(obj.id); 13 var e = (evt) ? evt: window.event; 14 //判断浏览器的类型,在基于ie内核的浏览器中的使用cancelBubble 15 if (window.event) { 16 e.cancelBubble = true; 17 } else { 18 //e.preventDefault(); 19 //在基于firefox内核的浏览器中支持做法stopPropagation 20 e.stopPropagation(); 21 } 22 } 23 </script> 24 </head> 25 26 <body> 27 <div id="parent1" onclick="alert(this.id)" style="250px;background-color:yellow"> 28 <p> 29 This is parent1 div. 30 </p> 31 <div id="child1" onclick="alert(this.id)" style="200px;background-color:orange"> 32 <p> 33 This is child1. 34 </p> 35 </div> 36 <p> 37 This is parent1 div. 38 </p> 39 </div> 40 <br /> 41 <div id="parent2" onclick="alert(this.id)" style="250px;background-color:cyan;"> 42 <p> 43 This is parent2 div. 44 </p> 45 <div id="child2" onclick="doSomething(this,event);" style="200px;background-color:lightblue;"> 46 <p> 47 This is child2. 48 </p> 49 </div> 50 <p> 51 This is parent2 div. 52 </p> 53 </div> 54 </body> 55 56 </html>

把代码直接复制后,打开当点击child1时不仅会弹出 child1, 对话框还会弹出 parent1,这就是冒泡事件的;

但是单击chile2只会弹出child2却不会弹出 parent2,这便是应用了阻止冒泡事件的特效的效果。

事件冒泡的优点和缺点:

1.那些需要创建的以及驻留在内存中的事件处理器少了。

这是很重要的一点,这样我们就提高了性能,并降低了崩溃的风险。
2.在DOM更新后无须重新绑定事件处理器了。

如果你的页面是动态生成的,比如说通过Ajax,你不再需要在元素被载入或 者卸载的时候来添加或者删除事件处理器了。
潜在的问题也许并不那么明显,但是一旦你注意到这些问题,你就可 以轻松地避免它们:你的事件管理代码有成为性能瓶颈的风险,所以尽 量使它能够短小精悍。

不是所有的事件都能冒泡

blur、focus、load和unload不能像其它事件一样冒泡。事 实上blur和focus可以用事件捕获而非事件冒泡的方法获得(在IE之外的其它浏览器中)。
需要注意的是:

如果你的代码处理mousemove事件的话你遇上性能瓶颈的风险可就大了,因为mousemove事件触发非常频繁。而mouseout则因为其 怪异的表现而变得很难用事件代理来管理。

附:

事件的冒泡有什么好处呢?

想 象一下现在我们有一个10列、100行的HTML表格,你希望在用户点击 表格中的某一单元格的时候做点什么。比如说我有一次就需要让表格中的每一个单元格在被点击的时候变成可编辑状态。如果把事件处理器加到这1000个单元格 会产生一个很大的性能问题,并且有可能导致内存泄露甚至是浏览器的崩溃。相反地,使用事件代理的话,你只需要把一个事件

1 function getEventTarget(e) {
2 e = e || window.event;
3 return e.target || e.srcElement;
4 }

e这个变量表示的是一个事件对象,我们只需要写一点点跨浏览器的代码来返回 目标元素,在IE里目标元素放在srcElemtn属性或event.toElement属性中,而在其它浏览器里则是target或event.relatedTarget属性。

接下来就是editCell函数了,这个函数调用到了 getEventTarget函数。一旦我们得到了目标元素之后,剩下的事情就是看看它是否是我们所需要的那个元素了。

1 function editCell(e) {
2 var target = getEventTarget(e);
3 if(target.tagName.toLowerCase() === 'td') {
4 // DO SOMETHING WITH THE CELL
5 }
6 }

在editCell函数中,我们通过检查目标元素标签名称的方法来确定它是 否是一个表格的单元格。这种检查也许过于简单了点;如果它是这个目标元素单元格里的另一个元素呢?我们需要为代码做一点小小的修改以便于其找出父级的td 元素。如果说有些单元格不需要被编辑怎么办呢?此种情况下我们可以为那些不可编辑的单元格添加一个指定的样式名称,然后在把单元格变成可编辑状态之前先检 查它是否不包含那个样式名称。选择总是多样化的,你只需找到适合你应用程序的那一种。

原文来自http://lengend.iteye.com/blog/1013372  略有改动

处理器添加到table元素上就可 以了,这个函数可以把点击事件给截下来,并且判断出是哪个单元格被点击了。

代 码很简单,我们所要关心的只是如何检测目标元素而已。比方说我们有一个 table元素,ID是“report”,我们为这个表格添加一个事件处理器以调用editCell函数。editCell函数需要判断出传到table 来的事件的目标元素。考虑到我们要写的几个函数中都有可能用到这一功能,所以我们把它单独放到一个名为getEventTarget的函数中:

免责声明:文章转载自《JS冒泡事件与处理》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇关于 devbridge-autocomplete 插件多选操作的实现方法你理解我的意思么?下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

更新js缓存办法

http://zhenggm.iteye.com/blog/680600 遇到的问题:在访问量比较大的系统中,我们需要将一些静态的文件在客户端缓存,以减少下载的流量,从而加快客户端访问的速度。但是缓存会带来一个问题,就是如何在服务端更新完文件之后,客户端能够及时得到更新。 解决思路:1. 在一个配置文件中维护js文件map; 2. 在页面中通过js ma...

Excel.Application手册

----转载:http://blog.csdn.net/xxfigo/article/details/6618129 定制模块行为(1) Option Explicit '强制对模块内所有变量进行声明    Option Private Module '标记模块为私有,仅对同一工程中其它模块有用,在宏对话框中不显示    Option Compare T...

js正则匹配获取文件名

//获取文件名,不带后缀 var file_name=file_path.replace(/(.*/)*([^.]+).*/ig,"$2"); //获取文件后缀 1.var FileExt=file_path.replace(/.+./,""); 2.var fileExtension = file_path.substring(file_path.l...

python操作Excel模块openpyxl

1、 安装 pip install openpyxl 想要在文件中插入图片文件,需要安装pillow,安装文件:PIL-fork-1.1.7.win-amd64-py2.7.exe · font(字体类):字号、字体颜色、下划线等 · fill(填充类):颜色等 · border(边框类):设置单元格边框 · alignment(位置类):对齐方式 · ...

JS与CSS阻止元素被选中及清除选中的方法总结

有时候,我们希望阻止用户选中我们指定区域的文字或内容。 举个栗子,有时候用户在一个区域执行频繁的点击操作,一不小心傲娇地点多了,就会选中当前区域的内容。 再举个栗子,制作轮播组件的时候,点击下一页,若点击的快的话,浏览器会识别为双击。 双击的默认效果是选中整片区域,这时候轮播图组件就会被表示忧郁的蓝色幕布盖住,多忧桑啊~ 你看,这妹子多赞啊,可是你一紧张...

excel合并单元格数据读取

import xlrdapply_dic = []def get_excel(excel_path): with xlrd.open_workbook(excel_path) as workbook : name_sheets = workbook.sheet_names() #获取Excel的sheet表列表,存储是sheet表名...