事件机制(事件冒泡与事件捕获)
2015-06-20 21:22
435 查看
<div id="outer"> <p id="inner">Click me!</p> </div>
事件冒泡
微软提出了名为事件冒泡(event bubbling)的事件流。时间冒泡就是指事件会从最内层的元素开始发生,一直向上传播,直到document对象。因此上面的例子在事件冒泡的概念下发生click事件的顺序应该是p -> div -> body -> html -> document
事件捕获
网景提出另一种事件流名为事件捕获(event capturing)。与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。上面的例子在事件捕获的概念下发生click事件的顺序应该是document -> html -> body -> div -> p
Netscape Navigator不会将页面上的很多元素暴漏给事件
在DOM事件流中,“DOM2级事件”中规定的事件流同时支持了事件捕获阶段和事件冒泡阶段
穿插一个小片段,解释一下这里的dom2级事件。
使用事件处理程序有三种方式:
1、HTML事件处理程序
如:<div id="outer"> <p id="inner" onclick="alert("我是html事件处理程序");">Click me!</p> </div> 2、DOM0级事件处理程序
如:<div id="outer"> <p id="inner">Click me!</p> </div><script type="text/javascript">
var pBtn=document.get
ElementById("inner");
pBtn.onclick=function(){ }
</script>
3、[b]DOM2级事件[/b]
就是用addEventListener()等类型的,在事件处理上IE和DOM也是有区别的,
IE中绑定事件和解绑为attachEvent(),detachEvent(),
DOM中的为addEventListener(),removeEventListener()
那么如何兼容此问题呢?如下代码,通过if..else类型判断
window.onload=function(){ var go=document.getElementById('go'), box=document.getElementById('box'); eventUtil.addHandler(box,'click',function(){ alert('我是整个父盒子'); }); eventUtil.addHandler(go,'click',function(e){ //e=eventUtil.getEvent(e); e=e || window.event; alert(eventUtil.getElement(e).nodeName); eventUtil.preventDefault(e); eventUtil.stopPropagation(e); }); }
js
应用例子:
<ul id="color-list"> <li>red</li> <li>yellow</li> <li>blue</li> <li>green</li> <li>black</li> <li>white</li> </ul>
如果点击页面中的li元素,然后输出li当中的颜色,我们通常会这样写:
(function(){ var color_list = document.getElementById('color-list'); var colors = color_list.getElementsByTagName('li'); for(var i=0;i<colors.length;i++){ colors[i].addEventListener('click',showColor,false); }; function showColor(e){ var x = e.target; alert("The color is " + x.innerHTML); }; })();
这样的代码再正常不过了,但是,如果页面上有几百个元素需要绑定(假设),那么务必就要绑定几百次啦。
这样问题就出现了:
第一:大量的事件绑定,性能消耗,而且还需要解绑(IE会泄漏) 第二:绑定的元素必须要存在 第三: 后期生成HTML会没有事件绑定,需要重新绑定 第四: 语法过于繁杂
在实际的开发当中,利用事件流的特性,我们可以使用一种叫做事件代理的方法。
利用事件流的特性,我们只绑定一个事件处理函数也可以完成:
(function(){ var color_list = document.getElementById('color-list'); color_list.addEventListener('click',showColor,false); function showColor(e){ var x = e.target; if(x.nodeName.toLowerCase() === 'li'){ alert('The color is ' + x.innerHTML); } } })();
使用事件代理的好处不仅在于将多个事件处理函数减为一个,而且对于不同的元素可以有不同的处理方法。假如上述列表元素当中添加了其他的元素(如:a、span等),我们不必再一次循环给每一个元素绑定事件,直接修改事件代理的事件处理函数即可。
关于事件对象
在IE中事件对象是windows的一个属性event
oDiv.onclick=function(){
var oEvent=window.event;
}
DOM标准则说,event对象必须作为唯一参数传给事件处理函数,
oDiv.onclick=function(){
var oEvent=window.arguments【0】;
}
或者
oDiv.onclick=function(oE[b]vent){[/b]
}
可用event.type获取事件对象的类型
event.target获取事件对象的目标
event.stoppropagation()阻止冒泡
在Jquery中如何用呢?
具体来说,事件委托就是事件目标自身不处理事件,而是把处理任务委托给其父元素或者祖先元素,甚至根元素(document)
委托这么好的特性 jQuery 当然不会放过,所以就衍生出 .bind()、.live() .on()和.delegate(),jQuery 的事件绑定有多个方法可以调用,以 click 事件来举例:
click方法 bind方法 delegate方法 on方法
这里要清楚的认识:不管你用的是(click / bind / delegate)之中哪个方法,最终都是 jQuery 底层都是调用 on 方法来完成最终的事件绑定。因此从某种角度来讲除了在书写的方便程度及习惯上挑选,不如直接都采用 on 方法来的痛快和直接。
所以在新版的 API 中都这么写到:
.on()方法事件处理程序到当前选定的 jQuery 对象中的元素。在jQuery 1.7中,.on()方法提供绑定事件处理的所有功能、效果不言而喻了,除了性能的差异,通过委托的事件还能很友好的支持动态绑定,只要 on 的delegate 象是 HTML 页面原有的元素,由于是事件的触发是通过Javascript的事件冒泡机制来监测,所以对于所有子元素(包括后期通过JS生成的元素)所有的事件监测均能有效,且由于不用对多个元素进行事件绑定,能够有效的节省内存的损耗。
相关文章推荐
- Bootstrap里的文件作用
- Node.js基础一 环境配置、JS基础、创建WebSite
- 7.测试与调试
- shell小技巧
- 【BestCoder #45】
- php面向对象基本概念(Final关键字)
- java实现七种排序 (插入排序, 希尔排序, 插入排序, 快速排序, 简单选择排序, 堆排序, 归并排序)
- 《人,绩效和职业道德》读后感
- Swift 数组和字典
- 11gR2 OUI安装界面的System Class和 Desktop Class
- C语言回顾(四、字符串及其处理函数重写)——iOS开发基础
- Linux字符设备编程(五)之struct class
- C/C++各种类型int、long、double、char表示范围(最大和最小)
- SSH无需密码密钥登录
- WebApp开发之--"rem"单位
- 《人,绩效和职业道德》
- Readline Keys
- 外网如何访问内网数据库
- Ubuntu 14.04 安装 Nvidia 私有驱动并进行双显卡切换
- Codeforces Round #299 (Div. 2) 题解