WebAPIs基础知识03

Wenn 于 2022-09-09 发布

事件流

事件触发后文档的执行流程

  • 捕获阶段-父到子
    • 从DOM开始逐级迭代,直到找到对应的目标源(反向的冒泡阶段)
  • 冒泡阶段-子到父
    • 从目标源开始逐级向上传递,直到最终到DOM,此阶段所有元素都会执行该事件;如果父子都监听有相同类型的事件,点击子事件源之后父元素也会执行子元素执行的事件
DOM.addEventListener('事件',function(),true); //开启捕获阶段执行
DOM.addEventListener('事件',function(),false); //默认捕获阶段不执行
//只要事件执行,那必然有捕获阶段和冒泡阶段;即便开启捕获阶段,冒泡阶段依旧执行;
//当不开启捕获阶段时,捕获阶段依旧执行;一个事件同一时间只可以开启一个阶段

因为事件流会导致其他可能的问题,所以我们可以阻止事件冒泡或捕获

const doc = document.querySelector('div');
doc.addEventListener('click', fn1)
function fn1(e){		//e是事件执行时产生的对象
    e.stopPropagation();  //语法:事件对象.stopPropagation 阻止事件冒泡
}

const link = document.querySelector('a');
link.addEventListener('click', fn2)
function fn2(e){
    e.preventDefault();  //阻止元素的默认行为
}

document.addEventListener('click', fn3)
function fn3(e){
    consloe.log(e.target); //输出根事件源,即目标事件源
}

on和事件事件监听的区别

  • on:同类型的事件只有一个,不可以开启事件捕获
  • addEventListener: 同类型的事件可以有多个,可以开启捕获
//DOM L0
const btn = documen.querySelector('.btn');
btn.onclick = function(){console.log(1)}; //绑定事件
btn.onclick = function(){console.log(2)}; //最终控制台仅输出2,前面一个事件会被后面同类型事件覆盖

//DOM L2
const btn = document.querySelector('.btn');
btn.addEventListener('click',function(){console.log('A')}); //绑定事件
btn.addEventListener('click',function(){console.log('B')});
//最终输出A,B  监听事件可以同时存在

解绑事件

//DOM L0
const btn = documen.querySelector('.btn');
btn.onclick = function(){console.log(1)};
btn.onclick = null; //将btn的click事件解除绑定

//DOM L2
const btn = document.querySelector('.btn');
btn.addEventListener('click',function(){console.log('A')}); //无法解绑,函数为匿名函数,无函数名称

btn.addEventListener('click', fn4)
function fn4(){
    console.log('B')
}
//语法:事件源.removeEventListen('事件类型', 函数名)
btn.removeEventListener('click', fn4)

鼠标事件

  • mouseenter、mouseleave 不支持冒泡
  • mouseove、mouseout 支持冒泡
<div>
    <p></p>
</div>
const p = document.querySelector('p');
const div = document.querySelector('div');

p.addEventListener('mouseenter',()=>{console.log('p')});
div.addEventListener('mouseenter',()=>{console.log('div')});
//此时我们仅点击p,控制台最终输出p

p.addEventListener('mouseover',()=>{console.log('p')});
div.addEventListener('moseover',()=>{console.log('div')});
//此时我们仅点击p,控制台最终输出p,div

事件委托

子孙元素事件委托给上级元素;原理是根据事件冒泡

<ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>
//1.将事件给上级元素注册
//2.利用事件对象.target找到目标源
//3.利用tagName返回元素的大写标签名判断是否是我们需要的元素
const ul = document.querySelector('ul');
ul.addEventListener('click',(e)=>{
    if(e.target.tagName === 'LI')e.target.style.background = '#0ff';
    //判断受点击的是否是li,如果是则执行
    //元素.tagName  将会返回元素的大写标签名
    //div.tagName 等于DIV
})

加载事件

//语法:事件源.addEventListener('load',()=>{console.lod('加载完毕')}),等该目标资源加载完毕之后输出

//判断页面所有资源加载完毕,则给window添加load事件
window.addEventListener('load',()=>{console.log('所有资源加载完毕')});

//主要用在js文件在head中,设置window检测所有资源加载之后在执行该js
//DOM加载: DOMContentLoaded
document.addEventListener('DOMContentLoaded', ()=>{console.log('document加载完毕')});
//使document标签加载完毕即可执行,不用等待外部资源执行;DOM加载先于window加载执行

页面滚动事件

监听整个页面滚动

window.addEventListener('scroll',()=>{console.log('页面进行滚动了')});

页面尺寸事件

只要页面的尺寸发生改变,就会触发该事件

window.addEventListener('resize',()=>{console.log('页面尺寸改变了')});