在不同的浏览器之间存在不同的dom实现,Netscape将其源代码以Mozilla贡献给开源社区之后,发展成Mozilla的事件模式和DOM标准最为接近。
事件流,在IE4.0中开发者所尝试的,其意味着在页面上可有不仅一个,甚至多个元素响应同一个事件,点击页面上的按钮,实际上是点击了按钮,他的容器以及整个页面。事件的发生顺序即事件流是这一切的差别衍化。
冒泡型事件即是从最特定的事件目标到最不特定的时间目标对象。在IE冒泡到html再到达document元素,在Mozilla会到达html->document->window。
捕获型事件和冒泡相反,从最不特定的开始直到最特定的元素。
dom是支持上述两种模式的,即是先发生捕获型再到冒泡型:
window->document->html->body->div
div->body->html->document->window
dom事件模型最独特的性质是,文本节点也触发事件。
事件使用户或浏览器自身的进行的特定的行为,所以这些事件有属于自己专属的名字:click load mouseover等对事件的响应相应称为监听函数onclick onmouseover onload等
在javascript中的监听函数用小写,在html上面大小写任意。
在IE中使用attchEvent()和detachEvent()来给事件附加处理函数
//
var fnClick = function () {
alert("clicked");
}
var fnClick2 = function () {
alert("clicked");
}
var fnClick3 = function () {
alert("clicked");
}
//IE方法attchEvent detachEvent
var oDiv = document.getElementById("clickDiv");
oDiv.attchEvent("onclick", fnClick);
oDiv.attchEvent("onclick", fnClick2);
oDiv.onclick = fnClick3;
//do
//some
//other
//things
oDiv.detachEvent("onclick", fnClick);
//DOM提供的是addEventListener() 和 removeEventListener()
oDiv.addEventListener("click", fnClick, true); //true代表在捕获阶段 false代表在冒泡阶段
//对于在捕获阶段加入的处理函数,其移除相应的也需要指定是捕获阶段
//传统模式下直接oDiv.onclick = fnClick3;是加入在冒泡阶段的
在发生事件时获取事件信息是重要的操作,事件对象只在发生事件时才被创建,而且只有在处理函数才能访问,函数执行完毕,事件对象就会被销毁。
同样IE和DOM方式存在差异。
在IE中window.event就是该对象,她只能在事件发生时访问,执行完毕就会销毁,实际上对于符合dom标准的事件处理函数应当这样写:
oDiv.onclick = function () {
var oEvent = arguments[0];
}
oDiv.onclick = function (oEvent) {
}
如果不这样,抱歉到时候就会产生获取不到事件的情况,反正我是犯过这样的错误。
事件的属性和方法
oDiv.onclick = function (oEvent) {
//获取事件的类型返回click mouseover 等
var sType = oEvent.type;
//获取按键代码
var iKeyCode = oEvent.keyCode;
//检测shift alt ctrl是否被按下
var bShift = oEvent.shiftKey;
var bAlt = oEvent.altKey;
var bCtrl = oEvent.ctrlKey;
//获取客户端坐标(浏览器窗口的距离坐标)
var iClientX = oEvent.clientX;
var iClientY = oEvent.clientY;
//获取屏幕坐标
var iScreenX = oEvent.screenX;
var iScreenY = oEvent.screenY;
}
//获取目标
//IE中属性srcElement DOM 用的是oTarget DOM下的目标可以是文本节点 IE不能
var oTarget = oEvent.target;
//获取字符代码
//在DOM下,keyCode 和 charCode是相分离的 即按键的代码和字符相分离
var iCharCode = oEvent.charCode;
var sChar = String.fromCharCode(iCharCode);
//使用isChar判断是否是char
if (oEvent.isChar) {
}
//阻止事件的默认行为
//在IE中
oEvent.returnValue = false;
//在Mozilla中调用
//oEvent.preventDefault();
//举例 用户点击页面时,阻止使用上下文菜单
document.body.oncontextmenu = function (oEvent) {
if (isIE) {
oEvent = window.event;
oEvent.returnValue = false;
} else {
oEvent.preventDefault();
}
}
事件的类型:鼠标事件 键盘事件 HTML事件 突变事件 不列举时间的属性
跨平台的事件
//移除事件
EventUtil.removeEventHandler = function (oTarget, sEventType, fnHandler) {
if (oTarget.removeEventListener) {
oTarget.removeEventListener(sEventType, fnHandler, false);
} else if (oTarget.detachEvent) {
oTarget.detachEvent("on" + sEventType, fnHandler);
} else {
oTarget["on" + sEventType] = null;
}
}
EventUtil.formatEvent = function (oEvent) {
if (isIE && isWin) {
oEvent.charCode = (oEvent.type == "keypress") ? oEvent.keyCode : 0;
oEvent.eventPhase = 2;
oEvent.isChar = (oEvent.charCode > 0);
oEvent.pageX = oEvent.clientX + document.body.scrollLeft;
oEvent.pageY = oEvent.clientY + document.body.scrollTop;
oEvent.preventDefault = function () {
this.returnvalue = false;
};
if (oEvent.type == "mouseout") {
oEvent.relatedTarget = oEvent.toElement;
} else if (oEvent.type == "mouseover") {
oEvent.relatedTarget = oEvent.fromElement;
}
oEvent.stopPropagation = function () {
this.cancelBubble = true;
}
oEvent.target = oEvent.srcElement;
oEvent.time = (new Date()).getTime();
}
return oEvent;
}
EventUtil.getEvent = function () {
if (window.event) {
return this.formatEvent(window.event);
} else {
return EventUtil.getEvent.caller.arguments[0];
}
}