深入理解DOM中的事件对象
2016-07-15 21:23
183 查看
1.在触发DOM上的某个事件时,会在事件处理程序函数中会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。先看个例子:
event.type属性表示事件类型。
event的属性currentTarget意思是事件处理程序当前正在处理事件的那个元素,target意思是事件的目标。在事件处理程序内部,对象this始终等于currentTarget的值,而target则只包含事件的实际目标。看个例子:
把事件处理程序直接指定给目标元素btn,则this、currentTarget和target包含相同的值。如果把事件处理程序注册在btn的父节点上(例如document.body),那么:
target元素等于btn元素,因为它是click事件真正的目标,由于没有注册事件处理程序,结果click冒泡到document.body上,在那里事件得到了处理。
一个函数处理多个事件:
event有个preventDefault()方法,阻止特定事件的默认行为。
event.stopPropagation()方法用于立即停止事件在DOM层次中的传播,即取消进一步的事件捕获或冒泡。例如:
如果不调用event.stopPropagation(),就会出现两个警告框。可是调用了这个方法后,click事件不会传播到document.body,因此就不会触发这个元素上的onclick事件处理程序。
2.再来看看IE中的事件对象
event对象作为window对象的一个熟悉存在。例子:
IE中event获取事件目标的属性是srcElement,:
因为this对象是根据事件处理程序的作用域确定的,所以上面两个不一样。
event.returnValue属性相当于DOM中的preventDefault()方法,只要将returnValue设置为false,就可以阻止默认行为:
event.cancelBubble属性与DOM中的stopPropagation()方法作用相同,都是用来停止事件冒泡的。由于IE不支持事件捕获,因而只能取消事件冒泡,但stopPropagation()可以同时支持事件捕获和冒泡。
将cancelBubble设置为true,就可阻止事件通过冒泡而触发document.body中注册的事件处理程序,只出现一个警告框。
3.跨浏览器的事件对象
4.如果事件处理程序过多,会占用内存,导致性能变差。解决办法是用事件委托。就是制定一个事件处理程序,管理某一类型的所有事件。例如:click事件会一直冒泡到document层次,就是说我们可以为整个页面制定一个onclick事件处理程序,而不必为每个单击的元素分别添加事件处理程序。例如:
如果在一个复杂的web应用程序中都使用这种方式,那就会有无数的代码添加事件处理程序,然而可以 事件委托技术解决,就是在DOM树的尽量最高的层次添加一个事件处理程序:
把事件委托给目标的父元素或者祖先元素,在ul添加添加一个onclick事件处理程序,由于所有目标元素都是这个元素的子节点,而且他们也会过得一个onclick事件,由于事件会冒泡,所以点击事件最终会被ul元素的处理事件程序处理。采用事件委托技术只添加了一个事件处理程序,占用的内存更少。
移除事件处理程序,在不需要的时候移除,也能提高性能,如果内存中留有那些过时不用的空事件处理程序,会造成内存和性能问题。
我们一般会用removeChild()和replaceChild()方法,但更多的是发生在使用innerHTML替换页面中的某一部分,如果把带有事件处理程序的元素用innerHTML替代原先的内容,那么原先添加到元素中的事件处理程序可能无法被当做垃圾回收。例子:
点击按钮就将按钮移除并替换成一个消息,在开发中很流行,但问题是,当按钮被从页面中移除时,它还带着一个事件处理程序。设置innerHTML可以把按钮移走,但事件处理程序仍然与按钮保持着引用关系,那么有些浏览器可能会把元素对事件处理程序的引用保存在内存中,生成了空事件处理程序,如果你知道某个事件即将被移除,那么最好手工处理:
var btn = document.getElementById("myBtn"); btn.onclick = function(event) { alert(event.type); //"click" } btn.addEventListener("click", function(event) { alert(event.type); //"click" }, false);
event.type属性表示事件类型。
event的属性currentTarget意思是事件处理程序当前正在处理事件的那个元素,target意思是事件的目标。在事件处理程序内部,对象this始终等于currentTarget的值,而target则只包含事件的实际目标。看个例子:
var btn = document.getElementById("myBtn"); btn.onclick = function(event) { alert(event.currentTarget === this); //true alert(event.target === this); //true };
把事件处理程序直接指定给目标元素btn,则this、currentTarget和target包含相同的值。如果把事件处理程序注册在btn的父节点上(例如document.body),那么:
document.body.onclick = function(envent) { alert(event.currentTarget === document.body); //true alert(this === document.body); //true alert(event.target === document.getElementById("myBtn")); //true };
target元素等于btn元素,因为它是click事件真正的目标,由于没有注册事件处理程序,结果click冒泡到document.body上,在那里事件得到了处理。
一个函数处理多个事件:
var btn = document.getElementById("myBtn"); var handler = function(event) { switch(event.type) { case "click": alert("Clicked"); break; case "mouseover": event.target.style.backgroundColor = "blue"; break; case "mouseout": event.target.style.backgroundColor = "red"; break; } }; btn.onclick = handler; btn.onmouseover = handler; btn.onmouseout = handler;
event有个preventDefault()方法,阻止特定事件的默认行为。
event.stopPropagation()方法用于立即停止事件在DOM层次中的传播,即取消进一步的事件捕获或冒泡。例如:
var btn = document.getElementById("myBtn"); btn.onclick = function(event) { alert("Clicked"); event.stopPropagation(); }; document.body.onclick = function(event) { alert("Body Clicked"); };
如果不调用event.stopPropagation(),就会出现两个警告框。可是调用了这个方法后,click事件不会传播到document.body,因此就不会触发这个元素上的onclick事件处理程序。
2.再来看看IE中的事件对象
event对象作为window对象的一个熟悉存在。例子:
var btn = document.getElementById("myBtn"); btn.onclick = function() { var event = window.event; alert(event.type); //"click" }; btn.attachEvent("click", function(event) { alert(event.type); //"click" }); //也可以通过window取得event对象
IE中event获取事件目标的属性是srcElement,:
var btn = document.getElementById("myBtn"); btn.onclick = function() { var event = window.event; alert(event.srcElement === this); //true }; btn.attachEvent("onclick", function(event) { alert(event.srcElement === this); //false });
因为this对象是根据事件处理程序的作用域确定的,所以上面两个不一样。
event.returnValue属性相当于DOM中的preventDefault()方法,只要将returnValue设置为false,就可以阻止默认行为:
var link = document.getElementById("myLink"); link.onclick = function() { window.event.returnValue = false; } //阻止链接默认行为
event.cancelBubble属性与DOM中的stopPropagation()方法作用相同,都是用来停止事件冒泡的。由于IE不支持事件捕获,因而只能取消事件冒泡,但stopPropagation()可以同时支持事件捕获和冒泡。
var btn = document.getElementById("myBtn"); btn.onclick = function() { alert("Clicked"); window.event.cancelBubble = true; }; document.body.onclick = function() { alert("Body Clicked"); };
将cancelBubble设置为true,就可阻止事件通过冒泡而触发document.body中注册的事件处理程序,只出现一个警告框。
3.跨浏览器的事件对象
var EventUtil = { getEvent: function(event) { return event ? event : window.event; }, getTarget: function(event) { return event.target || event.srcElement; }, preventDefault: fuction(event) { if(event.preventDefaule()) { event.preventDefaule(); } else { event.returnValue = false; } }, stopPropagation: function(event) { if(event.stopPropagation()) { event.stopPropagation(); } else { event.cancelBubble = true; } } }; btn.onclick = function(event) { event = EventUtil.getEvent(event); var target = EventUtil.getTarget(event); //等等 }
4.如果事件处理程序过多,会占用内存,导致性能变差。解决办法是用事件委托。就是制定一个事件处理程序,管理某一类型的所有事件。例如:click事件会一直冒泡到document层次,就是说我们可以为整个页面制定一个onclick事件处理程序,而不必为每个单击的元素分别添加事件处理程序。例如:
<ul id="lists"> <li id="goSomewhere">Go</li> <li id="doSomething">Do</li> <li id="sayHi">Hi</li> </ul> var item1 = document.getElementById("goSomewhere"); var item2 = document.getElementById("doSomething"); var item3 = document.getElementById("sayHi"); EventUtil.addHandler(item1, "click", function(event) { location.href = "http://www.google.com"; }); EventUtil.addHandler(item2, "click", function(event) { alert("Me"); }); EventUtil.addHandler(item3, "click", function(event) { alert("Hi"); });
如果在一个复杂的web应用程序中都使用这种方式,那就会有无数的代码添加事件处理程序,然而可以 事件委托技术解决,就是在DOM树的尽量最高的层次添加一个事件处理程序:
var list = document.getElementById("lists"); EventUtil.addHandler(list, "click", function(event) { event = EventUtil.getEvent(event); var target = EventUtil.getTarget(event); switch(target.id) { case "goSomewhere": location.href = "http://www.google.com"; break; case "doSomething": alert("Me"); break; case "sayHi": alert("Hi"); break; } });
把事件委托给目标的父元素或者祖先元素,在ul添加添加一个onclick事件处理程序,由于所有目标元素都是这个元素的子节点,而且他们也会过得一个onclick事件,由于事件会冒泡,所以点击事件最终会被ul元素的处理事件程序处理。采用事件委托技术只添加了一个事件处理程序,占用的内存更少。
移除事件处理程序,在不需要的时候移除,也能提高性能,如果内存中留有那些过时不用的空事件处理程序,会造成内存和性能问题。
我们一般会用removeChild()和replaceChild()方法,但更多的是发生在使用innerHTML替换页面中的某一部分,如果把带有事件处理程序的元素用innerHTML替代原先的内容,那么原先添加到元素中的事件处理程序可能无法被当做垃圾回收。例子:
<div id="myDiv"> <input type="button" value="Click me" id="myBtn"> </div> <script type="text/javascript"> var btn = document.getElementById("myBtn"); btn.onclick = function() { //执行某些任务 document.getElementById("myDiv").innerHTML = "Changing..."; } </script>
点击按钮就将按钮移除并替换成一个消息,在开发中很流行,但问题是,当按钮被从页面中移除时,它还带着一个事件处理程序。设置innerHTML可以把按钮移走,但事件处理程序仍然与按钮保持着引用关系,那么有些浏览器可能会把元素对事件处理程序的引用保存在内存中,生成了空事件处理程序,如果你知道某个事件即将被移除,那么最好手工处理:
<div id="myDiv"> <input type="button" value="Click me" id="myBtn"> </div> <script type="text/javascript"> var btn = document.getElementById("myBtn"); btn.onclick = function() { //执行某些任务 btn.onclick = null; //移除事件处理程序 document.getElementById("myDiv").innerHTML = "Changing..."; } </script>
相关文章推荐
- Python动态类型的学习---引用的理解
- 土人系列AS入门教程 -- 对象篇
- Mootools 1.2教程(2) DOM选择器
- DOM 事件流详解
- Dom在ajax技术中的作用说明
- C#托管堆对象实例包含内容分析
- C#实现获取不同对象中名称相同属性的方法
- javascript asp教程第十一课--Application 对象
- PowerShell中使用Out-String命令把对象转换成字符串输出的例子
- VBS教程:对象-正则表达式(RegExp)对象
- javascript针对DOM的应用分析(三)
- Dom 是什么的详细说明
- javascript针对DOM的应用分析(五)
- C#检查指定对象是否存在于ArrayList集合中的方法
- javascript针对DOM的应用实例(一)
- sql2008启动代理未将对象应用到实例解决方案
- 牛叉的Jquery――Jquery与DOM对象的互相转换及DOM的三种操作
- C#编程自学之类和对象
- C++中对象的常引用、动态建立和释放相关知识讲解
- C++之类和对象课后习题简单实例