我们如何知道在网页中点击的部件到底是什么?
首先来看事件流定义,事件流描述的是从页面中接受事件的顺序。
IE团队在最初方案中提出的是事件冒泡流,即事件从最具体元素向上,向最不具体元素传递
Netscape团队提出的是事件捕获流。最不具体元素先接收到事件。
虽然新版本都支持冒泡和事件捕获,但老版本浏览器不支持,所以一般写法用冒泡
DOM0级事件捕获
<body>
<button id="btn" value="click me" οnclick="showMessage();">click me</button>
</body>
<script type="text/javascript">
function showMessage(){
alert("click indeed!");
}
DOM2级事件捕获
addEventListener方法,参数是(要处理的参数名,处理函数,true/false表示是否在冒泡阶段调用事件处理程序)
<button id="btn" value="click me">click me</button>
</body>
<script type="text/javascript">
var btn = document.getElementById("btn");
btn.addEventListener("click", function showMessage(){
alert("click indeed!");
} ,false);
</script>
使用addEventListener的一个好处就是可以一次对一个object注册多个事件,顺序是顺着的顺序。
var btn = document.getElementById("btn");
btn.addEventListener("click", function showMessage1(){
alert("click!");
} ,false);
btn.addEventListener("click", function showMessage2(){
alert("click again!");
} ,false);
通过removeEventListener删除注册的事件
<body>
<button id="btn" value="click me">click me</button>
</body>
<script type="text/javascript">
var clickHandler = function showMessage(){
alert("click indeed!");
};
var btn = document.getElementById("btn");
btn.addEventListener("click", clickHandler ,false);
实际上这样是没法删除注册事件的。
匿名函数,无法直接删除,必须通过“手柄”进行删除,但实际上如果不通过handler是删除不了的,因为removeEventListener函数参数必须和前面相同,而即使removeEventListener中的函数和前面“一样”也没有用,原因和使用prototype定义类方法一样,js中function本质是对象,写两遍相同函数实际上定义的是两个不同的对象。要删除必须通过函数引用。
var btn = document.getElementById("btn");
btn.addEventListener("click", function showMessage(){
alert("click A!");
} ,false);
btn.removeEventListener("click", function showMessage(){
alert("click A!");
},false);
var clickHandler = function showMessage2(){
alert("click B!");
}
btn.addEventListener("click",clickHandler,false);
btn.removeEventListener("click", clickHandler, false);
IE6、7、8浏览器兼容办法
IE中提供的是attachEvent和detachEvent方法。写法少有不同,事件前要加“on”,比如点击事件应为“onclick”,没有第三个参数
var btn = document.getElementById("btn");
btn.attachEvent("onclick",function(){
alert("click!");
});
IE中触发顺序也不一样,是从下往上,下面例子里“click B”先触发
var btn = document.getElementById("btn");
btn.attachEvent("onclick",function(){
alert("click A!");
});
btn.attachEvent("onclick",function(){
alert("click B!");
});
还有一点很重要的不一样,FF中的域是绑定的组件本身,即this指向绑定事件的object本身,IE中this指向的是window
FF、Chrome
<body>
<button id="btn" value="click me">click me</button>
</body>
<script type="text/javascript">
window.name = "hello world";
var btn = document.getElementById("btn");
btn.addEventListener("click",function(){
alert(this.id);
},false);
</script>
IE 6、7、8
window.name = "hello world";
var btn = document.getElementById("btn");
btn.attachEvent("onclick",function(){
alert(this.name);
});
删除事件方法与removeEventListener相同,在此不赘述。
浏览器兼容写法:
类EventUtil
var EventUtil = {
addHandler:function(obj,eventType,handler)
{
if(obj.addEventListener)
{
obj.addEventListener(eventType,handler,false);
}
else if(obj.attachEvent)
{
obj.attachEvent("on"+eventType,handler);
}
else
{
obj["on"+eventType]=handler;
}
},
delHandler:function(obj,eventType,handler)
{
if(obj.removeEventListener)
{
obj.removeEventListener(eventType,handler,false);
}
else if(obj.detachEvent)
{
obj.detachEvent("on"+eventType,handler);
}
else
{
obj["on"+eventType]=null;
}
}
};
var target = document.getElementById("btn");
var clickHandler = function(){
alert("Hello world");
}
EventUtil.addHandler(target,"click",clickHandler);