JavaScript中的事件流详解

一.事件流

事件流是对事件执行过程的描述,就是整个事件的流动过程。

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

简言之,捕获阶段是【从父到子】的传导过程,冒泡阶段是【从子向父】的传导过程

1.捕获和冒泡

       a.如果事件是在捕获阶段执行的,我们称为捕获模式,它会先执行父盒子事件再去执行子盒子事件。  (从上到下)

       b.如果事件是在冒泡阶段执行的,我们称为冒泡模式,它会先执行子盒子事件再去执行父盒子事件,默认是冒泡模式。 (从下到上)

DOM对象.addEventListener('点击事件',函数,true)        

结论:

  1. addEventListener 第3个参数决定了事件是在捕获阶段触发还是在冒泡阶段触发
  2. addEventListener 第3个参数为 true 表示捕获阶段触发false 表示冒泡阶段触发,默认值为 false
  3. 事件流只会在父子元素具有相同事件类型时才会产生影响
  4. 绝大部分场景都采用默认的冒泡模式(其中一个原因是早期 IE 不支持捕获

2.阻止冒泡

a.概述

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

<body>

  <div class="father">

    <div class="son"></div>

  </div>

  <script>

    const fa = document.querySelector('.father')

    const son = document.querySelector('.son')

    document.addEventListener('click', function () {

      alert('爷爷')

    })

    fa.addEventListener('click', function () {

      alert('爸爸')    //点击father div会冒泡到document上的点击事件

    })

    son.addEventListener('click', function (e) {

      alert('儿子')

      // 组织流动传播  事件对象.stopPropagation()7

      e.stopPropagation()

    })

  </script>

</body>

 b.注意

鼠标经过事件:

mouseover 和 mouseout 会有冒泡效果

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

<body>

  <div class="dad">

    <div class="baby"></div>

  </div>

  <script>

    const dad = document.querySelector('.dad')

    const baby = document.querySelector('.baby')

    dad.addEventListener('mouseover', function () {

      console.log('鼠标经过')

    })

    dad.addEventListener('mouseout', function () {

      console.log('鼠标离开')

    })

  </script>

</body>

现在解析一下这个不常用的mouseover和mouseout,我先从大div进去一直进到小div,再从里面出来到初始位置,控制台输出结果如下

        鼠标进入小div会同时产生离开和经过,因为是在大div上绑定的点击事件,所有离开大div时会产生离开,但是接下来进入小div,你的鼠标也在移动,虽然它的身上并没有绑定相应鼠标事件,但是在它身上发生了鼠标移动,它还是会冒泡到大div上相同类型的事件,即为产生了鼠标经过的输出,下面的同理.

        总结一下

1.如果父绑定了和子触发事件不同的事件处理函数,那子冒泡到父,父确实不会执行函数

2.但是事件确实是传递了,只是因为父没有绑定同名事件的对应函数,所以没有表现出来

3.不是说不绑定事件处理函数就不会冒泡,还是会冒泡的,参考上面的例子

二.事件委托

        事件委托是利用事件流的特征解决一些现实开发需求的知识技巧,主要的作用是提升程序效率。 大量的事件监听是比较耗费性能的,它利用的就是冒泡,先将事件委托到父元素上,然后让子元素能够取到它,大大减少事件监听的总数。

不用事件委托绑定监听事件

使用事件委托绑定事件(根据就是很多相同的子元素都要绑定相同的事件,但是循环绑定会耗费性能,所以把事件绑定到父元素身上,等着子元素冒泡到父元素然后激发相应事件)

三.其它事件

1.页面加载事件

A.        加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件

有些时候需要等页面资源全部处理完了做一些事情

事件名:load

监听页面所有资源加载完毕:

window.addEventListener('load', function() {
    // xxxxx
})

B.        当初始HTML文档被完全加载和解析完成之后,DOMContentLoaded事件被触发,无需等待样式表,图像等完全加载

事件名:DOMContentLoaded

document.addEventListener('DOMContentLoaded', function () {

           

        })

2.元素滚动事件

滚动条在滚动的时候持续触发的事件

如果整个body的长度或宽度大于浏览器窗口显示的范围,就可以设置相应的元素滚动事件

window.addEventListener('scroll', function() {
    // xxxxx
})

其中scrollTop属性是指已经滚动到的位置距离初始位置的距离,返回的是数字

<script>

        const div = document.querySelector('div')

        // div.addEventListener('scroll', function () {

        //     console.log(div.scrollTop);     //控制台输出滚动距离

        // })

        window.addEventListener('scroll', function () {

            const n = document.documentElement.scrollTop   //指整个HTML界面距离界面最上方滚动的距离

            if (n >= 100) {

                div.style.display = 'block'    //控制div的出现和消失

            } else {

                div.style.display = 'none'

            }

        })

    </script>

像上面例子中的div如果文字溢出,可以直接加上滚动条效果,用css加入overflow: scroll;属性即可,如果想要加入滚动事件,再模仿上面的步骤就行

3.页面尺寸事件

a.会在窗口尺寸改变时触发事件

window.addEventListener('resize', function() {
    // xxxxx
})

b.检测屏幕宽度

c.获取元素可见部分宽高(不含边框border,margin,滚动条等)

        clientWidth和clientHeight

clientTop和clientLeft的大小就是border的大小,border为0则它们也为0

四.元素尺寸和位置

适用于比如说网页滑动到达某个元素之后要触发什么事件,这个时候就可以用offsetTop精确知道距离,再根据这个写相应元素滚动事件即可

对比和总结

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值