要想让 JavaScript 对用户的操作作出响应,首先要对 DOM 元素绑定事件处理函数。所谓事件处理函数,就是处理用户操作的函数,不同的操作对应不同的名称。
在JavaScript中,有三种常用的绑定事件的方法:
在DOM元素中直接绑定;
<input type="button" value="click me" onclick="hello()">
<script>
function hello(){
alert("hello world!");
}
</script>
在JavaScript代码中绑定;
<input type="button" value="click me" id="btn">
<script>
document.getElementById("btn").onclick = function(){
alert("hello world!");
}
</script>
绑定事件监听函数。
事件监听
优点:常规的事件绑定只执行最后绑定的事件,而事件监听可以绑定多个事件,还可以解除相应的绑定。
A、W3C标准的事件监听
我们在绑定事件监听函数时(注册事件)的时候,通常使用的是 捕获 或者 冒泡 的 一种,绝大多数是冒泡:
obj.addEventListener("click", func, true); // 捕获方式
obj.addEventListener("click", func, false); // 冒泡方式
事件只会因为捕获或者冒泡触发一次!
注:IE8以下不支持。
var btn = document.getElementById("myBtn");
btn.addEventListener("click", fun1, false);
btn.addEventListener("click", fun2, false);
btn.removeEventListener("click", fun1, false);
btn.removeEventListener("click", fun2, false);
function fun1(){
alert(this.id);
}
function fun2(){
alert("123456");
}
B、IE标准的事件监听
var btn = document.getElementById("myBtn");
var handler = function(){
alert("Clicked");
};
btn.attachEvent("onclick", handler);
//这里省略了其他代码
btn.detachEvent("onclick", handler);
C、跨浏览器的事件处理程序(兼容IE8及以下),整合了W3C标准与IE标准。
//定义:
var EventUtil = {
addHandler: function(element, type, handler){
if (element.addEventListener){
element.addEventListener(type, handler, false);
} else if (element.attachEvent){
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
},
removeHandler: function(element, type, handler){
if (element.removeEventListener){
element.removeEventListener(type, handler, false);
} else if (element.detachEvent){
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
}
};
//使用:
var btn = document.getElementById("myBtn");
var handler = function(){
alert("Clicked");
};
EventUtil.addHandler(btn, "click", handler);
//这里省略了其他代码
EventUtil.removeHandler(btn, "click", handler);
事件对象
在触发 DOM 上的某个事件时,会产生一个事件对象 event,这个对象中包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。例如,鼠标操作导致的事件对象中,会包含鼠标位置的信息,而键盘操作导致的事件对象中,会包含与按下的键有关的信息。所有浏览器都支持 event 对象,但支持方式不同。兼容的做法是:
var EventUtil = {
//返回event对象
getEvent: function(event){
return event ? event : window.event;
},
//返回事件的目标
getTarget: function(event){
return event.target || event.srcElement;
},
//取消事件的默认行为,(a链接元素、input的submit状态,都有默认行为)javascript的return false只会阻止默认行为,而是用jQuery的话则既阻止默认行为又防止对象冒泡。
preventDefault: function(event){
if (event.preventDefault){
event.preventDefault();
} else {
event.returnValue = false;
}
},
//阻止事件冒泡
stopPropagation: function(event){
if (event.stopPropagation){
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
使用:
btn.onclick = function(event){
event = EventUtil.getEvent(event);
}; //获得event
事件委托
事件委托就是利用冒泡的原理,把事件加到父元素或祖先元素上,触发执行效果,优点:
- 事件委托可以显著的提高事件的处理速度,减少内存的占用。
- 动态的添加DOM元素,不需要因为元素的改动而修改事件绑定。
<ul id="myLinks">
<li id="goSomewhere">Go somewhere</li>
<li id="doSomething">Do something</li>
<li id="sayHi">Say hi</li>
</ul>
<script>
var list = document.getElementById("myLinks");
EventUtil.addHandler(list, "click", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
switch(target.id){
case "doSomething":
document.title = "I changed the document's title";
break;
case "goSomewhere":
location.href = "http://www.wrox.com";
break;
case "sayHi":
alert("hi");
break;
}
});
</script>
移除事件
第一种情况,从文档中移除带有事件处理程序的元素时。这可能是通过纯粹的 DOM 操作,例如使用removeChild()和 replaceChild()方法,但更多地是发生在使用 innerHTML 替换页面中某一部分的时候。如果带有事件处理程序的元素被 innerHTML 删除了,那么原来添加到元素中的事件处理程序极有可能无法被当作垃圾回收。
所以,要先移除事件处理程序,再删除元素。
第二种情况,就是卸载页面的时候。如果在页面被卸载之前没有清理干净事件处理程序,那它们就会滞留在内存中。每次加载完页面再卸载页面时(可能是在两个页面间来回切换,也可以是单击了“刷新”按钮),内存中滞留的对象数目就会增加,因为事件处理程序占用的内存并没有被释放。
一般来说,最好的做法是在页面卸载之前,先通过 onunload 事件处理程序移除所有事件处理程序。在此,事件委托技术再次表现出它的优势——需要跟踪的事件处理程序越少,移除它们就越容易。对这种类似撤销的操作,我们可以把它想象成:只要是通过 onload 事件处理程序添加的东西,最后都要通过 onunload 事件处理程序将它们移除。
事件类型
UI(User Interface,用户界面)事件,当用户与页面上的元素交互时触发;
焦点事件,当元素获得或失去焦点时触发;
鼠标事件,当用户通过鼠标在页面上执行操作时触发;
滚轮事件,当使用鼠标滚轮(或类似设备)时触发;
文本事件,当在文档中输入文本时触发;
键盘事件,当用户通过键盘在页面上执行操作时触发;
合成事件,当为 IME(Input Method Editor,输入法编辑器)输入字符时触发;
变动(mutation)事件,当底层 DOM 结构发生变化时触发。
网友评论