事件流
事件流指从页面接收事件的顺序,分为冒泡(IE)和捕获
'DOM2级事件'规定的事件流包括三部分:捕获、处于目标阶段、冒泡
事件处理程序
1 DOM 0级事件处理方式
通过dom元素的事件处理程序属性添加,在冒泡阶段被处理,例如:
<button id="my-btn">click me</button>
var oBtn = document.getElementById('my-btn');
oBtn.onclick = function () {
console.log('click');
};
/* 移除 */
oBtn.onclick = null;
这种方法任何浏览器都支持。
2 DOM 2级事件处理方式
提供了两个方法用来添加和删除事件处理程序,即addEventListener和removeEventListener。
它们都接受三个参数:处理的事件名、处理函数、表示是否使用捕获的标志。例如:
<button id="my-btn">click me</button>
var clickHandler = function () {
console.log('click');
};
var oBtn = document.getElementById('my-btn');
/* 添加点击事件 在冒泡阶段使用 */
oBtn.addEventListener('click', clickHandler, false);
/* 移除刚才的点击事件 */
oBtn.removeEventListener('click', clickHandler, false);
这种方式适合非IE浏览器。
3 IE事件处理方式
提供了两个方法用来添加和删除事件处理程序,即attachEvent和detachEvent。
它们都接收两个参数:处理的事件名(需要在前面加on,例如:'onclick')、处理函数,会在冒泡阶段处理,例如:
<button id="my-btn">click me</button>
var clickHandler = function () {
console.log('click');
};
var oBtn = document.getElementById('my-btn');
oBtn.attachEvent('onclick', clickHandler);
oBtn.detachEvent('onclick', clickHandler);
特殊的是,attachEvent添加的多个处理函数执行顺序与添加顺序相反。
4 兼容多个浏览器的事件添加和删除
var EventUtil = {
addHandler: function(element, type, handler) {
//w3c
if (element.addEventListener) {
element.addEventListener(type, handler, false);
}
//ie
else if (element.attachEvent) {
element.attachEvent('on' + type,handler);
} else {
element['on' + type] = handler;
}
},
removeHandler: function() {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent('on' + type, handler);
} else {
element['on' + type] = null;
}
}
}
事件对象
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象包含着所有与事件有关的信息。
1 兼容DOM的浏览器
所有事件对象都会包含的属性和方法
属性/方法 | 类型 | 读/写 | 说明 |
---|---|---|---|
type | string | 只读 | 事件类型 |
bubbles | bool | 只读 | 表示事件是否冒泡 |
cancelable | bool | 只读 | 表示是否可以取消事件的默认行为 |
currentTarget | Element | 只读 | 当前正在处理事件的元素 |
target | Element | 只读 | 事件的目标,个人认为就是触发事件的元素 |
trusted | bool | 只读 | 是浏览器生成的还是js代码生成的 |
defaultPrevented | bool | 只读 | 为true表示已经调用了preventDefault() |
detail | int | 只读 | 与事件相关的详细信息 |
eventPhase | int | 只读 | 调用事件处理程序的阶段。1表示捕获阶段,2表示处于目标阶段,3表示冒泡阶段 |
preventDefault() | Function | 只读 | 取消事件的默认行为,如果cancelable为true可以使用 |
stopImmediatePropagation() | Function | 只读 | 取消事件的进一步捕获或冒泡,同时阻止任何事件处理函数被调用 |
stopPropagation() | Function | 只读 | 取消事件的进一步捕获或冒泡,如果bubbles为true可以使用 |
无论是DOM0级还是DOM2级方式都可以在处理函数中定义event参数来获取事件对象
<button id="my-btn">click me</button>
var oBtn = document.getElementById('my-btn');
oBtn.onClick = function (event) {
console.log(event.type); // display click
};
oBtn.addEventListner('click', function (event) {
console.log(event.type); // display click
}, false);
2 IE
所有事件对象都会包含的属性。
属性/方法 | 类型 | 读/写 | 说明 |
---|---|---|---|
type | string | 只读 | 事件类型 |
srcElement | Element | 只读 | 事件目标,和target相同 |
cancelBubble | bool | 只读 | 默认值false,设置为true就可以取消冒泡。和stopPropagation()作用相同 |
returnValue | bool | 只读 | 默认值true,设置为false可以取消默认行为。和preventDefault()作用相同 |
获取事件对象
<button id="my-btn">click me</button>
使用DOM0级方式时,event作为window的一个属性存在
var oBtn = document.getElementById('my-btn');
oBtn.onClick = function () {
var event = window.event;
console.log(event.type); // display click
};
使用attachEvent添加的事件处理函数也会接收到一个event参数。
oBtn.attachEvent('onclick', function (event) {
console.log(event.type); // display click
});
完整的事件工具方法
var EventUtil = {
addHandler: function(element, type, handler) {
//w3c
if (element.addEventListener) {
element.addEventListener(type, handler, false);
}
//ie
else if (element.attachEvent) {
element.attachEvent('on' + type,handler);
} else {
element['on' + type] = handler;
}
},
removeHandler: function() {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent('on' + type, handler);
} else {
element['on' + type] = null;
}
},
/* 获取事件对象 */
getEvent: function (event) {
return event || window.event;
},
/* 获取事件源 */
getTarget: function (event) {
return event.target || event.srcElement;
},
/* 阻止默认行为 */
preventDefault: function (event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
/* 阻止捕获或者冒泡 */
stopPropagation: function (event) {
if (event.stopPropagation) {
event.stopPropagation()
} else {
event.cancelBubble = true;
}
}
}