事件监听方法、焦点事件,事件流,阻止冒泡|青训营

50 阅读2分钟

事件监听方法

1.运行结果会覆盖

 const btn = document.querySelector('button')
        // btn.onclick = function(){
        //     alert(11)
        // }
        // btn.onclick = function(){
        //     alert(22)
        // }

2.运行的时候会一一的出现,不会覆盖。

const btn = document.querySelector('button')
btn.addEventListener('click',function(){
            alert(11)
        })
        btn.addEventListener('click',function(){
            alert(22)
        })

焦点事件

focus有焦点触发

blur失去焦点触发

<body>
    <input type="text">
    <script>
        const input = document.querySelector('input')
        input.addEventListener('focus',function(){
            console.log('有焦点触发');
        })
        input.addEventListener('blur',function(){
            console.log('失去焦点触发');
        })
    </script>
</body>

事件流

事件流是对时间执行过程的描述,了解事件的执行过程有助于对事件的理解,提升开发实践中对事件运用的灵活度。

任意时间被触发总会经历两个阶段:【捕获阶段】和【冒泡阶段】。

捕获阶段是【从父到子】的过程,而冒泡阶段是【从子到父】。

<body>
    <h3>事件流</h3>
    <p>事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上</p>
    <div class="outer">
        <div class="inner">
            <div class="child"></div>
        </div>
    </div>
    <script>
        //获取嵌套的3个节点
        const outer = document.querySelector('.outer')
        const inner = document.querySelector('.inner')
        const child = document.querySelector('.child')

        //html元素添加事件
        document.documentElement.addEventListener('click',function(){
            console.log('html....');
        })

        //body元素添加事件
        document.body.addEventListener('click',function(){
            console.log('body....');
        })

        //外层盒子添加事件
        outer.addEventListener('click',function(){
            console.log('outer....');
        })

        //中间的盒子添加事件
        outer.addEventListener('click',function(){
            console.log('inner....');
        })

        //内层盒子添加事件
        outer.addEventListener('click',function(){
            console.log('child....');
        })
    </script>
</body>

执行上述代码后,当单击事件触发时,其祖先元素的单击事件也相机触发

结合事件流的特征可知,当某个元素被触发时,事件总会先经过祖先才能达到当前元素,然后再由当前元素向祖先传递,事件在流动的过程中遇到相同的事件便会被触发。

事件相继触发的【执行顺序】,事件的执行顺序是可控的,即在捕获阶段或者在冒泡阶段。

如果在冒泡阶段执行的,就称其为冒泡模式,先执行子盒子事件,再执行父盒子事件,默认是冒泡模式。

如果是在捕获阶段执行的,就称其为捕获模式,先执行父盒子事件再执行子盒子事件。

<body>
    <h3>事件流</h3>
  <p>事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上。</p>
  <div class="outer">
    <div class="inner"></div>
  </div>
  <script>
    const outer = document.querySelector('.outer')
    const inner = document.querySelector('.inner')

    //外层盒子
    outer.addEventListener('click',function(){
        console.log('outer...');
    })//这里的true表示捕获阶段执行事件

    inner.addEventListener('click',function(){
        console.log('inner...');
    },true)
  </script>
</body>

结论:

  • addEventListener第三个参数决定了事件是在捕获阶段还是冒泡阶段触发。

  • addEventListener第三个参数是true表示捕获阶段触发,默认值false为冒泡阶段触发。

  • 事件流只会在父子元素具有相同事件类型才会产生影响。

  • 绝大部分场景都采用默认的冒泡模式(其中一个原因是早期 IE 不支持捕获)。

阻止冒泡

阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响其对应的祖先元素。

<body>
    <h3>阻止冒泡</h3>
  <p>阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素。</p>
  <div class="outer">
    <div class="inner">
      <div class="child"></div>
    </div>
  </div>
  <script>
    //获取嵌套的3个节点
    const outer = document.querySelector('.outer')
    const  inner = document.querySelector('.inner')
    const  child = document.querySelector('.child')

    //外层的盒子
    outer.addEventListener('click',function(){
        console.log('outer...');
    })

    //中间的盒子
    inner.addEventListener('click',function(ev){
        console.log('inner...');
        //阻止事件冒泡
        ev.addEventListener()
    })

    //内层的盒子
    child.addEventListener('click',function(ev){
        console.log('child...');

        //借助事件对象,阻止事件向上冒泡
        ev.stopPropagation()
    })
  </script>
</body>

结论;事件对象中的ev.stopPropagation方法,专门用来阻止事件冒泡。

鼠标经过事件:

mouseover 和 mouseout 会有冒泡效果

mouseenter 和 mouseleave 没有冒泡效果 (推荐)