美文网首页
DOM2级事件的核心运行机制

DOM2级事件的核心运行机制

作者: 江平路 | 来源:发表于2020-08-28 15:06 被阅读0次
    image.png

    1、DOM0 事件绑定

    • 语法:元素.on事件行为=function(){}
    • 原理:给元素的私有属性赋值,当事件触发,浏览器会帮我们把赋的值执行,但是这样也导致 “只能给当前元素某一个事件行为绑定一个方法
    box.onclick = function () {
        console.log('哈哈哈~~');
    }
    box.onclick = function () {
        console.log('呵呵呵~~');
    } 
    复制代码
    

    只输出后面的:


    image.png
    • 移除
    box.onclick = function () {
        console.log('哈哈哈~~');
        //=>移除事件绑定:DOM0直接赋值为null即可
        box.onclick = null;
    }
    复制代码
    

    2、DOM2 事件绑定

    • 语法:

      • 元素.addEventListener(事件行为,function(){},true/false)
        • true/false 可以省略,默认是false
        • IE6~8中:元素.attachEvent('on事件行为',function(){})
    • 原理:

      • 基于原型链查找机制,找到EventTarget.prototype上的方法并且执行,此方法执行,会把给当前元素某个事件行为绑定的所有方法,存放到浏览器默认的事件池中(绑定几个方法,会向事件池存储几个)
      • 当事件行为触发,会把事件池中存储的对应方法,依次按照顺序执行 “给当前元素某一个事件行为绑定多个不同方法”

      事件池特点:

      • 基于addEventListener向事件池增加方法,存在去重的机制 “同一个元素,同一个事件类型,在事件池中只能存储一遍这个方法,不能重复存储”
    box.addEventListener('click', function () {
        console.log('哈哈哈~~');
    }, false);
    box.addEventListener('click', function () {
        console.log('呵呵呵~~');
    }, false);
    复制代码
    

    两个都能输出:

    image.png
    • 绑定注意点:DOM2事件绑定的时候,我们一般都采用实名函数
      • 目的:这样可以基于实名函数去移除事件绑定
      • 语法:box.addEventListener('click', fn, false);
    function fn1(){ console.log(1); }
    function fn2(){ console.log(2); }
    function fn3(){ console.log(3); }
    box.addEventListener('click', fn2, false); 
    box.addEventListener('click', fn3, false); 
    box.addEventListener('click', fn1, false); 
    //=>基于addEventListener向事件池增加方法,存在去重的机制 “同一个元素,同一个事件类型,在事件池中只能存储一遍这个方法,不能重复存储”
    box.addEventListener('click', fn1, false); // 所以此步跳过,不再存储
    box.addEventListener('mouseover', fn1, false); 
    
    image.png
    • 移除绑定:从事件池中移除,所以需要指定好事件类型、方法等信息(要和绑定的时候一样才可以移除)
      • 语法:box.removeEventListener('click', fn, false)
    function fn() {
        console.log('哈哈哈~~');
        //=>移除事件绑定:从事件池中移除,所以需要指定好事件类型、方法等信息(要和绑定的时候一样才可以移除)
        box.removeEventListener('click', fn, false);
    }
    box.addEventListener('click', fn, false); 
    
    

    3、特别注意的几点

    • -1)DOM0和DOM2可以混在一起用:执行的顺序以绑定的顺序为主
    box.addEventListener('click', function () {
        console.log('哔咔哔咔~~');
    });
    box.onclick = function () {
        console.log('哇咔咔~~');
    }
    box.addEventListener('click', function () {
        console.log('call~~');
    });
    
    
    image.png
    • -2)DOM0 比 DOM2 快
    • -3)DOM0中能做事件绑定的事件行为,DOM2都支持;DOM2里面一些事件,DOM0不一定能处理绑定,例如:transitionend、DOMContentLoaded...
    box.style.transition = 'opacity 1s';
    box.ontransitionend = function () {
        console.log('哇咔咔~~');
    }
    
    box.addEventListener('transitionend', function () {
        console.log('哇咔咔~~');
    }); 
    
    window.addEventListener('load', function () {
        //=>所有资源都加载完成触发
        console.log('LOAD');
    });
    window.addEventListener('DOMContentLoaded', function () {
        //=>只要DOM结构加载完就会触发
        console.log('DOMContentLoaded');
    }); 
    
    //=>$(document).ready(function(){})
    $(function () {
        //=>JQ中的这个处理(DOM结构加载完触发)采用的就是DOMContentLoaded事件,并且依托DOM2事件绑定来处理,所以同一个页面中,此操作可以被使用多次
    });
    /* JQ中的事件绑定采用的都是DOM2事件绑定,例如:on/off/one */
    复制代码
    

    4、window.onload$(document).ready()的区别

    • -1)$(document).ready()
      • 采用的是DOM2事件绑定,监听的是DOMContentLoaded这个事件,所以只要DOM结构加载完成就会被触发执行,
      • 而且同一个页面中可以使用多次(绑定不同的方法,因为基于DOM2事件池绑定机制完成的)
    • -2)window.onload
      • 必须等待所有资源都加载完成才会被触发执行,采用DOM0事件绑定,同一个页面只能绑定一次(一个方法),
      • 想绑定多个也需要改为window.addEventListener('load', function () {})DOM2绑定方式

    5、DOM0 和 DOM2 的传播的区别

    • DOM0 绑定的方法,只能在目标阶段和冒泡阶段触发执行
    • DOM2绑定的方法,我们可以控制在捕获阶段执行
      • 元素.addEventListener(事件行为,function(){},true/false)
      • 第三个参数:不写 默认是 false
        • false:代表在冒泡阶段执行此方法
        • true:代表在捕获阶段执行此方法(基本没用过)

    浏览器常用的事件行为

    image.png

    1、鼠标事件

    鼠标点击:鼠标按下弹起算一次点击

    • onclick:点击(移动端click被识别为单击)
    • ondblclick:双击(大概是在 300ms 之间点击两次)
    • oncontextmenu:右键点击

    鼠标按下:不分左右键或者滚轮,只要按下/抬起就会触发

    • onmousedown:鼠标按下
    • onmouseup:鼠标抬起

    鼠标滚动

    • onmousewhell:鼠标滚轮滚动

    鼠标移动:鼠标尖端移动触发

    • onmousemove:鼠标移动

    鼠标经过

    • onmouseout:鼠标滑出
    • onmouseover:鼠标滑过(在表面经过即可)

    鼠标进入

    • onmouseenter:鼠标进入(进入到里面)
    • onmouseleave:鼠标离开

    思考:onmouseover 和 onmouseenter 的区别

    image.png
    • mouseover/mouseout 存在冒泡机制。划过和划出(鼠标在谁身上,相当于划过谁)
    • mouseenter/mouseleave 不存在冒泡传播机制。进入和离开。

    如何选用:项目中,如果一个容器中有后代元素,想要鼠标进入和离开做啥事,我们一般都用mouseenter和mouseleave。

    image.png

    2、键盘事件

    能绑定键盘事件的有:inputtextareawindowdocument.body

    • 如果想给不能编辑的元素绑定键盘事件,需要给这个元素加一个:contenteditable = "true"
    • onkeydown:按下某个键
    • onkeyup:抬起某个键
    • onkeypress:除Shift/Fn/CapsLock键以外,其它键按住(连续触发)

    3、表单事件

    使用范围:input ......

    • onfocus:获取焦点(光标进入input时,触发事件)
    • onblur:失去焦点(光标离开input时,触发事件)
    • oninput:内容改变(只要内容发生改变就会触发)
    • onchange:内容改变(并且失焦的时候才会触发)

    4、音视频事件

    使用范围:音频、视频

    • canplay:可以播放(资源没有加载完,播放中可能会卡顿)
    • canplaythrough:可以播放(资源已经加载完,播放中不会卡顿)
    • play:开始播放
    • playing:播放中
    • pause:暂停播放

    5、系统事件

    其它常用事件

    • window.onscroll:页面滚动
    • window.onresize:页面大小发生改变的时候触发
    • window.onload:页面资源加载完毕之后触发
    • img.onload :图片加载完成
    • window.onbeforeunload:当前页面关闭之前
    • window.onerror:资源加载失败

    6、移动端事件

    单手指事件模型 Touch

    • ontouchstart:手指碰到屏幕(手指按下)
    • ontouchmove:手指在屏幕上移动
    • ontouchend:手指离开屏幕(手指松开)
    • ontouchcancel:操作取消(一般应用于非正常状态下操作结束)

    多手指事件模型 Gesture

    • ongesturestart:手指碰到屏幕(手指按下)
    • ongesturechange / ongestureupdate:手指在屏幕上移动
    • ongestureend:手指离开屏幕(手指松开)
    • ongesturecancel:操作取消(一般应用于非正常状态下操作结束)

    7、其他事件

    • transitionend:动画过渡完成
    • onreadystatechange:AJAX请求状态改变事件
    • ......

    事件行为还有很多,这里我们暂时列举这些;更多的内容可以参考 MDN,事件参考; 或者可以查看元素的属性(属性中onxxx就是元素拥有的事件行为)

    链接:https://juejin.im/post/6844904144587718664

    相关文章

      网友评论

          本文标题:DOM2级事件的核心运行机制

          本文链接:https://www.haomeiwen.com/subject/dclqsktx.html