DOM事件流
1. DOM事件
1.1 事件三要素
- 事件源: 表示事件发生的地点,也就是事件被触发的元素。
- 事件类型: 表示事件以什么动作触发,例如:点击。
- 事件处理程序: 表示事件触发的响应,系统自动调用的函数。
1.2 事件三阶段
- 事件捕获阶段:事件从document元素捕获到目标元素时停止。(捕获目标元素)
- 事件目标阶段:事件在目标元素上发生并处理。但处理会被看成是事件冒泡阶段的一部分。(接收事件、触发事件)
- 事件冒泡阶段:事件从目标元素开始传递回document元素。(事件冒泡)
1.2 事件流
DOM事件流分为两种:
- 捕获型事件流
- 冒泡型事件流
1. 捕获型事件流
2. 冒泡型事件流
2. DOM事件要点
- 事件发生的顺序: 事件捕获–> 事件目标 --> 事件冒泡。(先捕获后冒泡)
- targetElement.addEventListener(eventType, callback[, options|useCapture]);
1. eventType: 不带on的事件类型,字符串。例如: click
2. callback: 当前事件所执行的回调函数
3. options|useCapture(可选)
useCapture: false,默认值表示事件在冒泡阶段执行callback。
true,表示事件在捕获阶段传递到targetElement时执行callback。
options: {
capture: true,//事件在捕获阶段传递到目标元素时执行回调函数
once: true,//表示最多只调用一次,之后自动移除
passive: true,//表示回调函数永远不会调用preventDefault()
}
// IE678不兼容
// 1. 注册事件,解决兼容性
function bind(targetElement, event, callback) {
if (targetElement.addEventListener) {
// 非IE
targetElement.addEventListener(event, callback);
} else {
// IE
targetElement.attachEvent('on' + event, callback);
}
}
// 2. 解绑事件,解决兼容性
function unbind(targetElement, event, funcName) {
if (targetElement.removeEventListener) {
// 非IE
targetElement.removeEventListener(event, funcName);
} else {
targetElement.detachEvent('on' + event, funcName);
}
}
3. 阻止事件默认行为、事件冒泡
3.1 阻止事件默认行为
- 标准浏览器: event.preventDefault();
- IE: event.returnValue = false;
- return false;//在原生JS中仅能阻止事件默认行为,在jQuery中可阻止事件默认行为与事件冒泡
// 阻止事件默认行为
function stopDefault(e){
if(e && e.preventDefault){
// 标准浏览器
e.preventDefault();
}else {
// 个别IE
e.returnValue = false;
return false;
}
}
3.2 阻止事件冒泡
- 标准浏览器: event.stopPropagation();
- IE: event.cancelBubble = true;
// 阻止事件冒泡
function stopBubble(e){
if(e && e.stopPropagation{
// 非IE
e.stopPropagation();
}else {
// IE
e.cancelBubble = true;
}
}
4. 事件冒泡、事件捕获意义(事件委托)
事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。(JavaScript高级程序设计)
4.1 为什么会出现事件委托?
当我们有1个li的时候,我们给li加上click事件,这样是完全没有问题的。但是当我们有成百上千个li呢,此时我们会怎么处理。
当然一种最简单的方法就是for循环遍历,然后给每个li都加上click事件,这样确实能实现。但html页面渲染速度是和DOM的操
作的多少挂钩的,而DOM操作的多少会和绑定事件的数量挂钩的,绑定的数量越多,页面渲染的越慢。此使用事件委托,可以解
决。事件委托的原理是事件冒泡,当我们给li添加事件的时候,此时事件流会顺着li向外层的ul流去,那么此时我们便可以只在ul上添加和li上相同的事件,便可以实现和在li上添加的相同的效果。
<ul id="ul1">
<li>你好</li>
<li>你好</li>
<li>你好</li>
<li>你好</li>
<li>你好</li>
<li>你好</li>
<li>你好</li>
<li>你好</li>
</ul>
// 未使用事件委托
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(){
alert(123);
}
}
// 使用事件委托
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(){
alert(123);
}
}