DOM2级事件是通过addEventListener添加事件的,IE8及以下是通过attchEvent
DOM2绑定事件
box.addEventListener("click",callback,false);
//IE8及以下
box.attachEvent("onclick",fn)
说明(addEventListener)
- 第一个参数:事件的类型(DOM0绑定事件是直接写onclick,DOM2绑定事件的时候,要省略on)
- 第二个参数:绑定的监听者(个人理解就是回调函数=>也就是点击时要执行的函数)
- 第三个参数:是一个boolean类型的值(true:表示方法在捕获阶段时执行;false:表示在冒泡传播阶段执行)
- 可以给同一个元素的同一个行为绑定不同的函数,谁先绑定谁先执行,但是不能给同一个元素的同一个行为绑定相同的函数(前提时同一个阶段)
可以通过removeEventListener移除元素上面的事件,但是添加的匿名函数无法移除
说明(attachEvent)
- 第一个参数:事件类型(必须是带on的)
- 第二个参数:要绑定的事件函数
DOM2级事件和DOM0级事件的区别:
1、阶段问题:DOM0级事件没有三个阶段,它只有冒泡阶段
不管怎么改变绑定事件的顺序,都不会影响它执行的顺序的,因为他没有捕获和目标阶段,只有冒泡阶段
let center = document.getElementById("center"),
outer = document.getElementById("outer"),
main = document.getElementById("main");
outer.onclick = function () {
console.log("outer")
}
main.onclick = function () {
console.log("main")
}
center.onclick = function () {
console.log("center")
}
但是DOM2级事件会通过三个阶段处理,它的处理顺序是:捕获阶段=>目标阶段=>冒泡阶段;有个注意的地方是,目标阶段的捕获和冒泡是根据他们绑定的顺序来决定他们的执行顺序的
let center = document.getElementById("center"),
outer = document.getElementById("outer"),
main = document.getElementById("main");
main.addEventListener("click", fn, true);
main.addEventListener("click", fn3, false);
outer.addEventListener("click", fn1, true);
outer.addEventListener("click", fn4, false);
center.addEventListener("click", fn2, true);
center.addEventListener("click", fn5, false);
//执行顺序
// fn=>f1=>f2=>f5=>f4=>fn3
function fn() {
console.log("main 捕获")
}
function fn1() {
console.log("outer 捕获")
}
function fn2() {
console.log("center 捕获")
}
function fn3() {
console.log("main 冒泡")
}
function fn4() {
console.log("outer 冒泡")
}
function fn5() {
console.log("center 冒泡")
}
- 绑定事件重复的问题:
DOM2级事件绑定,可以给同一个元素的同一个行为绑定不同的函数,谁先绑定谁先执行,但是给同一个元素的同一个行为绑定相同的函数只会执行一次,因为他不是给元素添加属性而是直接给他添加事件(前提是同一个阶段),DOM0级事件绑定不能给同一个元素的同一个行为绑定同一个函数,后绑定的事件会把前面绑定的事件覆盖掉(可以理解成是给元素添加属性)
- this问题
DOM2事件通过addEventListener绑定的监听者中的this指的是当前被绑定事件的这个元素,而通过attachEvent绑定的监听者中的this指向的是window
事件对象
box.onclick = function(e){
console.log(e)
}
- e就是事件对象:当触发元素的事件行为时,浏览器会给当前的方法默认传进一个对象,这个对象中包含了此次事件的一些信息;那这个对象就是事件对象;但是IE8及以下没有,把事件信息放到了window的event对象上了
常用的事件对象中的属性
属性名 | 属性值 |
---|---|
clientY | 当前鼠标点击的位置距离可视窗口上边的距离 |
clientX | 当前鼠标点击的位置距离可视窗口左边的距离 |
pageY | 当前鼠标点击的位置距离整个文档上边框的距离 |
pageX | 当前鼠标点击的位置距离整个文档左边框的距离 |
offsetY | 当前鼠标点击的位置距离盒子上边框的距离(当事件源发生改变时(e.target发生变化时会影响offsetY的值)) |
offsetX | 当前鼠标点击的位置距离盒子左边框的距离(当事件源发生改变时(e.target发生变化时会影响offsetY的值)) |
target | 当前的事件源(当前本绑定事件的元素) |
type | 当前事件的类型 |
兼容IE8的写法
e = e || window.event;
e.pageY = e.pageY || e.clientY + document.documentElement.scrollTop;
e.pageX = e.pageX || e.clientX +document.documentElement.scrollLeft;
e.target =e.target||e.srcElement;
事件的默认行为
常见的默认行为
- a标签的默认链接
- submit按钮的默认发送请求
可以通过e.preventDefault()阻止默认行为,但是IE8及以下不兼容我们可以设置returnValue的值为false也可以阻止他的默认行为
e.preventDafault = e.preventDefault || function(){
returnValue = false;
}
e.preventDefault();
冒泡传播
定义:给当前元素的子孙元素的事件行为绑定方法,当触发子孙元素身上的事件时,当前元素对应的事件行为也会随着触发,这种事件从内向外传播执行的方式就是事件冒泡传播;
阻止事件的冒泡传播
阻止事件的冒泡传播=>e.stopPropagation();
//兼容IE
event.stopPropagation = event.stopPropagation || function () {
event.cancelBubble = true;
};
event.stopPropagation();