DOM0事件绑定的特点
:
- 只有DOM元素天生拥有这个私有属性(onxxx事件私有属性),我们赋值的方法才叫事件绑定,否则属于设置自定义属性
- 移除事件绑定的时候,我们只需要赋值为null;
- 在DOM0事件绑定中,只能给当前元素的某一个事件行为绑定一个方法,绑定多个方法,最后一次的绑定的会替换前面绑定的
DOM2事件绑定的原理
- DOM2事件绑定使用的 addEventListener/attachEvent方法都是在eventTarget这个内置类的原型上定义的,我们调用的时候,首先要通过原型链找到这个方法,然后执行完成事件绑定的效果
- 浏览器会给当前元素的某个事件行为开辟一个事件池(事件队列)【浏览器有一个统一的事件池,每个元素绑定的行为都放在这里,通过相关标志区分】,当我们通过 addEventListener/attachEvent进行事件绑定的时候,会把绑定的方法放在事件池中;
- 当元素的某一行为被触发,浏览器回到对应事件池中,把当前放在事件池的所有方法按序依次执行
特点:
- 所有DOM0支持的行为,DOM2都可以用,DOM2还支持DOM0没有的事件行为(这样说比较笼统)
- (核心)
【浏览器会把一些常用事件挂载到元素对象的私有属性上,让我们可以实现DOM0事件绑定,DOM2:凡是浏览器给元素天生设置的事件在DOM2中都可以使用】
- DOM2中可以给
当前元素的某一事件行为绑定多个不同方法
(因为绑定的所有方法都放在事件池中); - 事件的移除:
事件类型、绑定的方法、传播阶段三个完全一致,才可以完成移除
(因此在绑定方法时,尽量不要用匿名函数,否则不好移除) - DOM0和DOM2绑定的方法是毫无联系的(因为是两套完全不同的机制),即使绑定的方法相同,也是执行两次,谁先绑定,就先执行谁
IE6-8事件池机制vs标准浏览器事件池机制(比较规范的回答)
1、向事件池中添加方法时,标准浏览器是使用addEventListener,IE6-8使用的是attachEvent;而且标准浏览器有自动去重的机制,已经添加的方法不允许再次添加。IE6-8没有去重机制;
2、浏览器执行事件池中的方法时,不仅把方法执行,还把事件对象当作实参传递给给对应的方法,但是也是有区别的,IE6-8传递的事件对象的值和window.event是相同 的,因此存在兼容问题;
3.当事件行为被触发,标准浏览器是依次执行,方法中的this指向当前元素;IE6-8下,是乱序执行,且方法中的this指向window;
不兼容的本质:IE6-8低版本浏览器对于他的内置事件池处理机制的不完善导致的。
DOM2事件绑定兼容处理机制原理:自己创建一个类似于标准浏览器的自定义事件池(针对IE6-8)
Function.prototype.myBind = function myBind(context = window, ...outer) { //使用ES6中的剩余运算符
if ('bind' in this) {
return this.bind(arguments);
}
return function (...inner) {
this.apply(context, outer.concat(inner));
}
};
冒泡是从里到外,捕获是从外到里
防止冒泡和捕获:
w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true
取消默认事件
w3c的方法是e.preventDefault(),IE则是使用e.returnValue = false;
IE6-8中添加事件attachEvent()
移除事件detachEvent()
没有第三个参数,因为ie6~ie8不支持事件捕获。
DOM2级事件中的第三个参数,是可选的布尔值,默认为false(事件冒泡),true(事件捕获)
DOM2阻止事件冒泡:
https://blog.csdn.net/weixin_39141044/article/details/83685146