最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 学习DOM事件机制

    正文概述 掘金(Blend)   2020-12-09   461

    DOM 事件

    • 事件是什么?

      在Web应用程序中,事件就是将应用程序内的发生的动作或者发生的事情告知浏览器,浏览器给出响应。

    • 事件和JavaScript有什么关系?

      事件是客户端(浏览器)的一种处理机制,事件机制与JavaScript并不存在存在直接联系,联系的建立是依靠客户端来实现的,事件机制本身并不是JavaScript语言的内容。

      简单来说,DOM事件并不是JavaScript的功能,而是浏览器支持的功能,我们只是使用JavaScript来完成事件的监听和对事件做出响应。

    事件绑定

    HTML内联绑定事件

    HTML中直接绑定DOM,就是在HTML的元素中使用<event>属性来绑定事件,比如onclick这样的on(type)属性,其中type指的就是DOM的事件(比如click),它可以给这个DOM元素绑定一个类型的事件。

    <button onclick="show();">Click Me</button> 
    <script> 
        function show() { 
        console.log('Show Me!')
        } 
    </script>
    

    JavaScript中绑定DOM事件

    在JavaScript中绑定DOM事件有两种方法:

    1. element.on(type) = listener

      let btn = document.querySelector('button') 
      btn.onclick = function () { 
          console.log("Show Me!"); //被覆盖
      };
      btn.onclick = function () { 
          console.log("Show Me again!"); //最终绑定
      };
      

      按照DOM事件级别分类,上面的方法是DOM0级事件,就是将一个函数赋值给一个事件处理属性,优点是降低HTML和JS的耦合,并且处理函数可以接收浏览器创建的事件对象event作为参数,缺点在于无法同时给同一个DOM元素绑定多个处理函数,执行上面两次绑定时,下面的函数就会覆盖上面的。

    2. element.addEventListener(type, listener, useCapture)

      参数:

      element:表示要监听事件的目标对象

      type:表示事件类型的字符串,比如click、change、touchstart等

      listener:当指定的事件类型发生时被对知到的一个对象,一般是是一个函数。

      useCapture:设置事件的捕获或者冒泡,它有两个值,其中true表示事件捕获,为false是事件冒泡,默认值为false

      <button>Click Me!</button>
      <script> 
        function show (e) { 
           console.log("Show Me!") 
            console.log(e)
        } 
        let btn = document.querySelector('button') 
        btn.addEventListener('click', show, false)
       </script>
      

      按照DOM事件级别分类,上面的方法是DOM2级事件,优点是可以给同一个DOM元素绑定多个处理函数,并且遵循“先绑定先触发”的原则,处理函数可以接收浏览器创建的事件对象event作为参数。

    事件对象

    当事件发生时,浏览器会创建一个事件对象,将详细信息放入这个对象当中,下图是把代码中点击事件对象event打印出来的结果。

    学习DOM事件机制

    Event对象在event第一次触发的时候被创建出来,并且一直伴随着事件在DOM结构中流转的整个生命周期(当事件结束后,可以认定为对象也消失了,所有当想一直使用event对象的数据时,可以赋值给其他对象来保留数据)。event对象会被作为第一个参数传递给事件监听的回调函数。我们可以通过这个event对象来获取到大量当前事件相关的信息,下面挑选几个重要的参数:

    • type (String):事件的名称

    • target (node):事件起源的DOM节点,可以理解为用户操作的元素

    • currentTarget?(node):当前回调函数被触发的DOM节点,可以理解为用户监听的元素

      ?详细信息MDN文档

    DOM事件流

     <div onclick="parent">
          <div onclick="child">click</div>
     </div>    
    

    上面的代码中,在子元素和父元素上都注册了点击事件,当点击文字时,是先触发父元素上的事件函数,还是子元素上的事件函数呢,这就需要一种约定去规范事件的执行顺序,就是事件执行的流程。 浏览器在发展的过程中出现了两种不同的规范:

    • IE9以下的IE浏览器使用的是事件冒泡,由内向外找监听函数。
    • Netscapte采用的是事件捕获,由外向内找监听函数。
    • 而W3C制定的Web标准中,是同时采用了两种方案,事件捕获和事件冒泡都可以。

    W3C事件模型

    学习DOM事件机制

    W3C规范中定义了三个事件传播阶段,依次是捕获阶段目标阶段冒泡阶段

    • 捕获阶段(Capture Phase):事件从window对象自上而下向目标节点传播的阶段;

    • 目标阶段(Target Phase):真正的目标节点正在处理事件的阶段;如果一个事件对象类型被标志为不能冒泡,那么对应的事件对象在到达此阶段时就会终止传播。

    • 冒泡阶段(Bubbling Phase):事件从目标节点自下而上向window对象传播的阶段。

      给DOM元素绑定事件都会经历三个传播阶段,当事件发生时,始终从根开始,沿着路径直到达到目标,然后再重新追溯根源,然后回到根。而其中启动事件的部分和事件从根向下寻找目标称为事件捕获阶段,从目标回到根的阶段为冒泡阶段。

    • IE的API:element.attachEvent('oncIick', (n) //指定为冒泡阶段被触发

    • Netscapte的API:element.addEventListener('cIick',fn) / /指定为捕获阶段被触发

    • W3C的API:element.addEventListener('cIick',fn,bool)

      bool没有值或值为falsy——冒泡

      bool值为ture——捕获

    事件中断

    现实中,很多时候我们并不希望目标元素的事件结束之后还去追溯其根源(冒泡)。在JavaScript中可以在事件对象上使用stopPropagation方法来阻止目标元素的冒泡事件,但是会不阻止默认行为。

      function show (e) { 
         e.stopPropagation();
      }
    

    取消默认事件

    • 浏览器默认事件

    许多事件会自动触发浏览器执行某些行为。

    例如:点击一个链接 会触发导航(navigation)到该 URL,点击表单的提交按钮 会触发提交到服务器的行为。

    • 取消方法
    1. 使用 event 对象的 event.preventDefault() 方法
    <a href="/" onclick="event.preventDefault()">here</a>
    
    1. return false
    <a href="/" onclick="return false">Click here</a>
    

    事件委托

    由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的委托(delegation)。

    适用场景

    场景一:给N个同级元素添加点击事件

    解决:使用事件委托,在父元素parent上设置监听函数

       <div id="parent">
            <button data-id="1">1</button>
            <button>2</button>
            <button>3</button>
            <button>4</button>
            <button>5</button>
        </div>
        <script>
            parent.addEventListener('click',(e)=>{
                const t=e.target
                if(t.target.toLowerCase()=='button'){
                    console.log("button被点击了");
                    console.log('button的data-id是'+t.dataset.id);
                }
            })
        </script>
    

    场景二:监听目前还不存在的元素的点击事件

    解决:先监听父元素, 等点击的时候看看是不是我想要监听的元素即可

        <div id="parent"> </div>
        <script>
            setTimeout(()=>{
                const button=document.createElement('button')
                button.textContent='button'
                parent.appendChild(button)
            },1000)
            parent.addEventListener('click',(e)=>{
                const t=e.target
                if(t.target.toLowerCase()=='button'){
                    console.log("button被点击了");
                }
            })
        </script>
    

    优点

    1. 减少内存消耗,提高性能

      参考场景一,不用单独给每个按钮绑定监听函数,我们只需要给父容器绑定函数即可,这样不管点击的是哪一个后代元素,都会根据冒泡传播的传递机制,把容器的click行为触发,然后把对应的方法执行,根据事件源(target),我们可以知道点击的是哪个子元素,从而完成不同的事。

    2. 动态绑定事件

      参考场景二,那么在元素动态发生变化时,就需要给新增的元素绑定事件,给即将删去的元素解绑事件,如果用事件代理就会省去很 多这样麻烦。

    参考

    事件绑定的姿势

    深入理解DOM事件机制


    起源地下载网 » 学习DOM事件机制

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元