Web API-DOM事件进阶! 事件流,事件委托,其他事件

107 阅读3分钟

一:事件流

事件流指事件完整执行过程中流动的路径

相同的事件才会有事件流

1,捕获阶段 (由大到小)

L0 没有事件捕获,只有事件冒泡

事件捕获:从DOM根元素开始去执行对应的事件(从外到里)

需要写相应代码才能看到结果

第三个参数传入为 true时, 代表捕获阶段触发 (L2)

如果不传,或传入为false时,为事件冒泡

2,冒泡阶段 (由小到大)

实际开发中以事件冒泡为主

事件冒泡:当一个元素事件触发时,同样的事件将会在该元素的所有祖先元素中依次被触发

2.1阻止冒泡

阻止事件流(流动)传播,保证事件在当前元素执行,从而不会影响其它的祖先元素

前提:阻止事件冒泡需要拿到事件对象

语法:

事件对象.stopPropagation()

  erzi.addEventListener('click',function(e){
         e.stopPropagation()
            alert('我是儿子')
        })
2.2阻止默认行为

事件对象.preventDefault

应用场景:比如阻止表单提交,链接跳转

 const a = document.querySelector('a')
       a.addEventListener('click',function(e){
           e.preventDefault()
       })
2.3解绑事件
 // 事件解绑 L0版本
        btn1.onclick = function(){
            console.log('绑定事件')
        }
        // 解绑 给btn2注册绑定事件 将btn1解绑
        btn2.onclick = function(){
            btn1.onclick = null
        }
 // L2 版本 匿名函数无法做事件解绑
        function fn () {
            console.log('绑定事件');
        } 
//绑定
btn1.addEventListener('click',fn)
​
//解绑 给btn2注册绑定事件 将btn1解绑
   btn2.addEventListener('click',function(){
            btn1.removeEventListener('click',fn)
        })

二:事件委托

利用事件冒泡的特点,给父元素注册事件,当我们触发子元素时,会冒泡到父元素身上,从而触发父元素的事件

优点:减少次数,提高性能

  const ul = document.querySelector('ul')
        //委托给Ul
        ul.addEventListener('click',function(e){
        //事件对象 .target.tagName 才能获取正在被触发的元素
            if (e.target.tagName === 'LI') {
                e.target.style.color = 'red'
            }
        })
  <!-- 需求 点击每个 li 让当前的li变红色 -->
    <ul>
        <li>第一个</li>
        <li>第二个</li>
        <li>第三个</li>
        <li>第四个</li>
        <li>第五个</li>
    </ul>

三 :其它事件

页面加载事件

加载外部资源(如图片,外联css和js等)加载完毕时触发的事件

// 等待页面所有资源加载完毕 再去执行回调函数 
// load 事件
window.addEventListener('load',function(){
    //获取
    const btn = document.querySelector('button')
    //点击事件
    btn.addEventListener('click',function(){
        console.log('111');
    })
})
// DOMContentLoaded 事件 无需等待样式,图片等完全加载 给document添加
document.addEventListener('DOMContentLoaded',function(){
    const btn = document.querySelector('button')
    //点击事件
    btn.addEventListener('click',function(){
        console.log('111');
    })
})

元素滚动事件

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

事件名 :scroll

scroll事件可以被两个对象注册

document(文档)对象注册

window 对象注册

    //document(文档)对象注册
        document.addEventListener('scroll',function(){
            console.log('滚起来了');
        })
   //1,监听整个页面滚动
        window.addEventListener('scroll',function(){
            console.log('滚起来了');
        })
 // 2,监听某个元素内部的滚动 
        //直接给元素添加
        const box = document.querySelector('.box')
        box.addEventListener('scroll',function(){
            console.log('内部滚动');

            //scrollTop  被卷的头部
            console.log(box.scrollTop);
        })

-scrollTop.html是可读写的小细节

 //滚动事件
        //scrollTop 可读写
        document.documentElement.scrollTop = 100
        window.addEventListener('scroll',function(){
            //必须写到滚动事件里面 获取最新数据
            const n =  document.documentElement.scrollTop
            // 得到的是数字型  不带单位
            console.log(n);
        })

页面尺寸事件

  • 窗口尺寸发生改变的时候触发的事件

resize

  //resize 浏览器窗口大小发生变化时触发的事件
        window.addEventListener('resize',function(){
            console.log(1);
        })
  • 检测屏幕宽度

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

clientWidth 和 clientHeight

  //clientWidth 和 clientHeight  获取元素可见部分宽高(不包含边框,margin,滚动条等)
       const  div = document.querySelector('div')
       console.log(div.clientWidth);
       console.log(div.clientHeight);

四:元素尺寸于位置-尺寸

获取宽高:

  • 获取元素 自身宽高,包含元素自身设置的宽高 (内容 + padding + border)
  • offserWitch 和 offsetHeight
  • 获取出来的是数值,方便计算
  • 注意:获取的是可视宽高,如果盒子是隐藏的,获取的结果是0

获取位子:

  • 获取元素距离自己定位父级元素的左 ,上距离
   const div = document.querySelector('div')
        const p = document.querySelector('p')
        //检测盒子的位置
        // console.log(div.offsetLeft);
        //offsetLeft 受父亲的影响 父级如果有定位 以父亲位置 父亲 没有定位找最近带有定位的元素
        console.log(p.offsetLeft);

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

带有定位的父级

如果都没有则以 文档左上角 为准

  • offsetLeft 和 offsetTop 注意只读属性

\