Dom事件是做网站前端开发,特别是web2.0类的,有更多用户交互的网站的一个挺重要的东西,我简单谈谈2个方面。
一个叫Event Flow,事件流,一个事件,比如一个简单的click,用户一点击,事件被触发,假设这个事件的监听函数(listener)有2个,一个是被加在一个table的td上,一个是加在这个td的父元素--table的tr上,那么,这两个监听函数将以什么顺序被触发呢?
有两个模型,一个是Mozilla家族的 Event Capturing,事件捕获,Trigger the elements from outer to inne,事件从最外层的函数向内传播,先table再tr再td。另外一个是IE家族的Event Bubbling,事件冒泡,Trigger the elements from inner to outer,与另一个刚刚相反。
W3C很投机,谁也不得罪,搞了个兼容的规定:Events are first captured until it reaches the target element, and then bubbled up.
不过双方目前谁有没有采取对方模型的意思,分别使用
stopPropagation, cancelBubble, preventDefault, returnValue等方法和属性,可以控制相应的事件流。
另外一个想介绍的方面是,事件的处理模型,Event handling model。这方面的模型比较统一和标准化,不过还是有差异。
首先是Dom Level 0的一系列模型,有inline model,最就是初学者常用的onclick=XX的模式的方法,这个方法有意思的一点是,如果使用onclick="return XX()"后得到false的话,会自动在各个浏览器中调用相应的preventDefault和returnValue=false,停止事件的默认行为。另外有Traditional Model,使用Dom方法拿到元素的Dom reference后,用dTd.onclick=XXX的方法添加监听函数。
然后是Dom Level 2的几个模型,首先是w3c标准的事件处理模型,有addEventListener,removeEventListener,dispatchEvent三个方法,mozilla家族都支持。另外一个是IE家族的Microsoft-specific model,看到这里可能我们都会觉得郁闷,为啥IE每次都格格不入呢?其实这次倒是冤枉它了,Microsoft-specific model是一个比W3C Dom Level 2早的模型,所以,不是微软故意刁难,确实是人家早。这个模型有attachEvent,detachEvent两个方法。
其实写这篇文章的动机就是不小心发现了w3c的dispatchEvent方法,这个我爱!可以用脚本模拟真正的用户在浏览器操作的行为呢…… 用来黑网站,搞自动填充表单提交再好不过!嗯,注意还有document.createEvent这种好方法。
例子代码如下:
function preventDef(event) {
event.preventDefault();
}
function addHandler() {
document.getElementById("checkbox").addEventListener("click",
preventDef, false);
}
function removeHandler() {
document.getElementById("checkbox").removeEventListener("click",
preventDef, false);
}
function simulateClick() {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
var cb = document.getElementById("checkbox");
var canceled = !cb.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
alert("canceled");
} else {
// None of the handlers called preventDefault
alert("not canceled");
}
}再给进一步阅读的三个链接
1 2 3