1.浏览器事件模型过程
浏览器事件模型中的过程主要分为三个阶段:捕获阶段、目标阶段、冒泡阶段。
捕获->目标->冒泡
2.监听事件的第三个参数
window.addEventListener('click', function(e){
console.log(e.target.nodeName) //指当前点击的元素
console.log(e.currentTarget.nodeName) //绑定监听事件的元素
}, true) //false为默认为冒泡,true为捕获
- e.target当前点击的元素
- e.currentTarget监听事件的元素
- false或不填为冒泡,true为捕获
3.阻止事件的传播
- e.stopPropagation()阻止冒泡和捕获阶段的传播。
- stopImmediatePropagation() 如果有多个相同类型事件的事件监听函数绑定到同一个元素,当该类型的事件触发时,它们会按照被添加的顺序执行。如果其中某个监听函数执行event.stopImmediatePropagation() 方法,则当前元素剩下的监听函数将不会被执行。
4.e.preventDefault()阻止默认事件
5.事件代理/事件委托
事件代理,又称之为事件委托。是JavaScript中常用绑定事件的常用技巧。“事件代理”即是把原本需要绑定在子元素的响应事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。
- 事件委托,可以减少事件注册,大量节省内存占用。比如在ul上代理所有li的click事件
const ul = document.querySelector("ul");
ul.addEventListener('click', function (e) {
const target = e.target;
if (target.tagName.toLowerCase() === "li") {
// LiList为伪数组
const liList = this.querySelectorAll("li");
const realList = Array.form(liList);
const index = realList.index(target);
alert(`内容为${target.innerHTML}, 索引为${index}`);
}
})
6.兼容性
- attachEvent——兼容:IE7、IE8; 不支持第三个参数来控制在哪个阶段发生,默认是绑定在冒泡阶段
- addEventListener——兼容:firefox、chrome、IE、safari、opera;
7.封装一个多浏览器兼容的绑定事件函数
class BomEvent {
constructor(element) {
this.element = element;
}
addEvent(type, handler) {
if (this.element.addEventListener) {
//事件类型、需要执行的函数、是否捕捉
// IE不支持事件捕获
this.element.addEventListener(type, handler, false);
} else if (this.element.attachEvent) {
this.element.attachEvent(`on${type}`, function () {
// IE7、IE8不支持箭头函数
handler.call(element);
});
} else {
this.element['on' + type] = handler;
}
}
removeEvent(type, handler) {
if (this.element.removeEnentListener) {
this.element.removeEnentListener(type, handler, false);
} else if (element.datachEvent) {
this.element.detachEvent('on' + type, handler);
} else {
// 赋值为null释放内存
this.element['on' + type] = null;
}
}
}
// 阻止事件 (主要是事件冒泡,因为IE不支持事件捕获)
function stopPropagation(ev) {
if (ev.stopPropagation) {
ev.stopPropagation(); // 标准w3c
} else {
ev.cancelBubble = true; // IE
}
}
// 取消事件的默认行为
function preventDefault(event) {
if (event.preventDefault) {
event.preventDefault(); // 标准w3c
} else {
event.returnValue = false; // IE
}
}