zoukankan      html  css  js  c++  java
  • 13-DOM二级事件与DMO0级事件-DOM三级事件

    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

  • 相关阅读:
    [日常] Go语言圣经-命令行参数
    [日常] Go语言圣经前言
    [日常] 搭建golang开发环境
    [日常] 研究redis未授权访问漏洞利用过程
    [日常] CentOS安装最新版redis设置远程连接密码
    [日常] Apache Order Deny,Allow的用法
    [日常] 读取队列并循环发信的脚本
    [日常] 20号日常工作总结
    [日常] SinaMail项目和技术能力总结
    [日常] MySQL的预处理技术测试
  • 原文地址:https://www.cnblogs.com/haoqiyouyu/p/14604536.html
Copyright © 2011-2022 走看看