Web APIs DOM事件进阶:事件流

ppgo8 于 2023-04-20 发布

Web APIs DOM事件进阶:事件流

表单复选框案例

image-20230418113202554

image-20230418113218933

案例1:当选中“全选”框时,下面的按钮要全部选中;当取消“全选”时,下面的按钮要全部取消。(大控制小)

案例2:当下面的小按钮选中的数量===3时,上面的”全选框“要选中;不===3,上面的”全选框“要不选中。(小控制大)

事件流与两个阶段说明

事件捕获

image-20230418115057101

如果对多个嵌套盒子都注册了同一种点击事件,那么在捕获阶段:执行的过程中,从大到小执行。

事件冒泡

目标:能够说出事件冒泡的执行过程

事件冒泡的概念:当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程称为事件冒泡。

简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件

阻止冒泡

image-20230419093520371

stopPropagation()是阻止的事件传播,因此也可能阻止冒泡或捕获

解绑事件

事件一旦绑定了在某些情况下可以解除。

L0:on事件方法

image-20230419093920258

L2:remove方法

image-20230419095334536

鼠标经过事件的区别

两种注册时间的区别

image-20230419171103218

事件委托

事件委托知识点

事件冒泡可以做事件委托。

委托场景:班里所有学生订了快递,快递小哥把快递送给班主任,班主任把快递转交给各个学生。有时候有些事件不需要亲自执行,而是交给父亲执行。

事件委托:事件委托是利用事件流的特征解决一些开发需求的知识技巧。


总结

  1. 事件委托的好处是什么?

    减少注册次数,提高程序性能

  2. 事件委托是委托给了谁?父元素

  3. 如何找到真正触发的元素标签?

    • 事件对象名.target.tagName,用来判断

    • 真正触发事件的对象:对象名.target

事件委托案例

使用事件委托实现:

image-20230419180637488

任务1:事件委托实现鼠标点击tab栏切换

// 核心代码
// 事件委托给父级元素
const ul = document.querySelector('ul') 
// 排他思想
ul.addEventListener('click',function (e){
    // 判断是否为点击的小a标签 (click 点击到的是最小的)
    if (e.target.tagName === 'A'){
    	// 1.别人移除
    	document.querySelector('.active').classList.remove('active') // 注意:第二个不添加.
    	// 2.自己添加
   		e.target.classList.add('active')
})

任务2:事件委托实现内容栏随着tab栏切换的功能

关键技术:

阻止默认行为

在某些情况下需要阻止默认行为的发生,比如 阻止链接的跳转、表单域跳转。

之前学的是阻止冒泡

e.preventDefault() // 阻止默认行为

小结

// 阻止冒泡
事件对象.stopPropagation()
// 阻止元素默认行为 e事件对象,事件处理函数第一个参数
e.preventDefault() 

其他事件

除了鼠标点击、经过、离开、光标、表单输入、键盘按下抬起外的其他事件。

目标:掌握新的事件,做更强的交互。

页面加载事件

load事件:全部web资源加载完毕

一般来说,代码从上往下按照顺序执行。

事件处理函数不是立即执行的,而是事件触发了才会执行。

DOMContentLoaded:HTML文档资源加载完毕


小结

1.页面加载事件有哪两个?如何添加?

页面滚动事件


小结

image-20230420112050973

页面尺寸事件

元素的尺寸与位置

image-20230421102339735

获取元素宽高

获取元素位置


总结

  1. offsetWidth和offsetHeight得到元素什么的宽高?

    内容+padding+border

  2. offsetTop和offsetLeft得到的位置以谁为准?

    • 带有定位的父级
    • 如果都没有,则以文档左上角为准

https://www.bilibili.com/video/BV1Y84y1L7Nn/?p=113&spm_id_from=pageDriver&vd_source=dde2f4dd432156027fedf9b1734ba705

bilibili案例没看

综合案例

业务需求和内容如下:

image-20230421153853286

实现方法,为了避免各个部分污染,因为可以放到不同的模块中做。:

image-20230421154127680

方法:立即执行函数

模块2遇到的问题,使用了一个if条件判断

image-20230421155827420

// 排他思想,这里很特别:因为一开始没有active类,需要条件判断一下才可以
const old = document.querySelector('.xtx-elevator-list .active') // 找不到返回null
// 判断:如果原来有类就移除,如果开始没有类,就不删除,所以不报错
if (old) old.classList.remove('active')
e.target.classList.add('active')

模块2解决方法:

image-20230421161208157其他Bug修复:

模块3分析: