ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

DOM事件进阶

2022-05-13 22:31:34  阅读:115  来源: 互联网

标签:function 进阶 DOM 元素 事件 addEventListener div document


事件流

事件流与两个阶段说明

概念

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

事件流

假设页面里有个div,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段

捕获阶段是 从父到子 冒泡阶段是从子到父

实际工作都是使用事件冒泡为主

事件捕获

概念

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

语法:事件源.addEventListener('事件方式',事件处理函数,是否使用捕获机制)

addEventListener第三个参数传入 true 代表是捕获阶段触发(很少使用)

若传入false代表冒泡阶段触发,默认就是false

若是用 L0 事件监听(on事件监听),则只有冒泡阶段,没有捕获

  <div>
    <p></p>
  </div>
  <script>
    // 事件监听:事件源.addEventListener('事件方式',事件处理函数,是否使用捕获机制)
    // 事件流:事件触发后的流程
        //  捕获阶段 true 
        // 冒泡阶段 false  默认
    const div = document.querySelector('div')
    const p = document.querySelector('p')

    div.addEventListener('click', function () {
      console.log('div')
    },true)

    p.addEventListener('click', function () {
      console.log('p')
    },true)

  </script>

事件冒泡

概念

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

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

L0事件监听,L2事件监听默认都是冒泡

  <div>
    <p></p>
  </div>
  <script>
    const div = document.querySelector('div')
    const p = document.querySelector('p')

    div.addEventListener('click', function () {
      console.log('div')
    })

    p.addEventListener('click', function () {
      console.log('p')
    })

  </script>

阻止冒泡

阻止事件冒泡

因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素

若想把事件就限制在当前元素内,就需要阻止事件冒泡

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

语法:事件对象.stopPropagation()

此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效

    p.addEventListener('click', function (e) {
      console.log('p')
      // 阻止事件冒泡
      e.stopPropagation()
    })

阻止默认行为

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

语法:事件对象.preventDefault()

  <a href="http://www.baidu.com">链接</a>
  <form action="http://www.baidu.com">
    <input type="submit" value="提交">
  </form>
  <script>
    const a = document.querySelector('a')
    const form = document.querySelector('form')

    a.addEventListener('click', function (e) {
      // 阻止a默认跳转行为
      // 事件对象.preventDefault()  阻止默认
      e.preventDefault()
    })
    form.addEventListener('click', function (e) {
      // 阻止表单默认提交行为
      e.preventDefault()
    })
  </script>

解绑事件

传统on注册(L0)

绑定事件:事件源.onxxxx = function () {}

解绑事件: 事件源.onxxxx = null

  • 同一个对象,后面注册的事件会覆盖前面注册(同一个事件)
  • 直接使用null覆盖偶就可以实现事件的解绑
  • 都是冒泡阶段执行的,无法开启捕获阶段
 <button>点击</button>
 <script>
     // 绑定事件
  btn.onclick = function () {
    console.log('onclick1')
  }

  btn.onclick = function () {
    console.log('onclick2')
  }
  // 解绑事件
  btn.onclick = null
  </script>

事件监听注册(L2)

绑定事件:事件源.addEventListener('事件类型', 处理函数)

解绑事件:事件源.removeEventListener('事件类型', 处理函数名)

  • 语法: addEventListener(事件类型, 事件处理函数, 是否使用捕获)
  • 后面注册的事件不会覆盖前面注册的事件(同一个事件)
  • 可以通过第三个参数去确定是在冒泡或者捕获阶段执行
  • 必须使用removeEventListener('事件类型', 事件处理函数名, 是否开启捕获阶段)
  • 匿名函数无法被解绑
 <button>点击</button>
 <script>
  const f1 = function () {
    console.log('addEventListener1')
  }

  const f2 = function () {
    console.log('addEventListener2')
  }

  // 绑定事件
  // 匿名函数,无法解绑
  btn.addEventListener('click', function () {
    console.log('addEventListener0')
  })

  btn.addEventListener('click', f1)

  btn.addEventListener('click', f2)

  // 解绑事件
  // 事件源.removeEventListener('事件类型', 事件处理程序的名称)
  btn.removeEventListener('click', f2)
  </script>

事件委托

概念

事件委托:把事件委托给上级元素,利用事件流的特征解决一些开发需求的知识技巧

优点:

减少注册次数,可以提高程序性能,动态创建的元素也可以有事件了

原理:

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

实现:

事件对象.target:最先触发事件的元素 ,标签

事件对象.target. tagName :可以获得真正触发事件的元素 ,返回大写的标签名

  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
    <li>10
      <a href="">链接</a>
    </li>
  </ul>
  <script>

    // 事件委托:把事件委托给上级元素
    /* 
    步骤:
       1.给上级元素注册事件
       2.利用事件对象.target找到最先触发元素
       3.用tagName查看是否是我们要找的元素 
       
     */

     const ul = document.querySelector('ul')

    //  注册事件
    ul.addEventListener('click', function (e) {
      // e.target有可能不是我们要找的元素,只有我们要找的元素才可以
      if (e.target.tagName === 'LI') {
        e.target.style.background = 'pink'
      }
    })

  </script>

事件委托步骤:

​ 1.给上级元素注册事件
​ 2.利用事件对象.target找到最先触发元素
​ 3.用tagName查看是否是我们要找的元素

其他事件

页面加载事件

load

事件名:load

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

使用场景:监听页面所有资源加载完毕: 给 window 添加 load 事件

 <script>
    // 加载事件:load
      //  当外部资源加载完成后触发的事件
      // 只要涉及带有路径的,都涉及加载
    // load:所有资源加载 绑定在window
    window.addEventListener('load', function () {
      console.log('页面所有资源加载完成后执行')
      const img = document.querySelector('img')
      console.log(img)
    })

  </script>

  <img src="./images/b01.jpg" alt="">
</body>

注意:不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件

<img src="./images/b01.jpg" alt=""> 
<script>
    // 加载事件:load
      //  当外部资源加载完成后触发的事件
      // 只要涉及带有路径的,都涉及加载
     const img = document.querySelector('img')

     img.addEventListener('load', function () {
       console.log('图片加载完成后执行')
     })
  </script>
</body>

DOMContentLoaded

事件名:DOMContentLoaded

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

使用场景: 监听页面DOM加载完毕: 给 document 添加 DOMContentLoaded 事件

 <script>
    // DOM加载:当初始的HTML文档加载 绑定在document
    document.addEventListener('DOMContentLoaded', function () {
      console.log('当初始的HTML文档被完全加载和解析完成之后执行')
      const img = document.querySelector('img')
      console.log(img)
    })

  </script>

  <img src="./images/b01.jpg" alt="">
</body>

滚动事件

绑定/添加滚动事件

事件名:scroll

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

使用场景: 谁有滚动条,给谁加滚动事件

  • 监听某个元素的内部滚动直接给某个元素加即可
  • 监听整个页面滚动: 给 window 或 document 添加 scroll 事件
<style>
    div {
      width: 200px;
      height: 600px;
      background-color: #eee;
      overflow-y: scroll;
    }
    body {
      height: 2000px;
    }
  </style>
 <script>
    // scroll:滚动事件 谁有滚动条,给谁加滚动事件
    const div = document.querySelector('div')
    div.addEventListener('scroll', function () {
      console.log(`向上滚动${div.scrollTop}px`)
  
    })

    // 如果整个页面有滚动条,加给widow
    window.addEventListener('scroll', function () {
      console.log('滚动ing...')
    })
  </script>

获取位置

scrollLeft和scrollTop (属性)

使用场景:

  • 在scroll事件里面获取被卷去的距离
  • 获取被卷出的大小, 获取元素内容往左、往上滚出去看不到的距离

这两个值是可读写的,不仅可以获取,还可以设置

  <script>
    const div = document.querySelector('div')
    div.addEventListener('scroll', function () {
      console.log(`向上滚动${div.scrollTop}px`)
    })

    window.addEventListener('scroll', function () {
      // 整个页面再往出卷,那么卷的是html的scrollTop
      // 获取html
      // const html= document.documentElement
      const html = document.querySelector('html')
      console.log(`向上滚动${html.scrollTop}px`)
    })

    // scrollTop不仅可以获取,还可以设置
    const btn = document.querySelector('input')
    btn.addEventListener('click', function () {
      // 返回顶部,设置上卷距离为0
      document.documentElement.scrollTop = 0
    }) 
  </script>

滚动到指定的坐标

语法:元素.scrollTo(x, y)

使用场景:把内容滚动到指定的坐标

btn.addEventListener('click', function () {
      // 返回顶部,设置上卷距离为0
      // document.documentElement.scrollTop = 0
      window.scrollTo(0,0)
    }) 

页面尺寸事件

绑定/添加滚动事件

事件名:resize

触发方式:窗口尺寸改变的时候触发事件

使用场景: 检测屏幕宽度: 给 window 添加 resize 事件

    window.addEventListener('resize', function () {
      const w = document.documentElement.clientWidth
      console.log(`当前页面宽度:${w}`)
    })

元素尺寸与位置

获取元素宽高

属性名:clientWidth和clientHeight

使用场景:获取元素的可见部分宽高:内容 + padding(不包含边框,margin,滚动条等)

clientWidth和clientHeight

属性名:offsetWidth和offsetHeight

使用场景:获取元素的自身宽高,包含元素自身设置的宽高、padding、border

元素尺寸

注意

  1. 获取出来的是数值,方便计算
  2. 获取的是可视宽高, 如果盒子是隐藏的,获取的结果是0
  3. 以上两种属性只能获取,不能设置
  4. 获取页面宽高,通常使用clientWidth和clientHeight,获取元素宽高,通常使用:offsetWidth和offsetHeight
<style>
    div {
      width: 200px;
      height: 200px;
      padding: 10px;
      margin: 10px;
      border: 10px solid #000;
    }
  </style>
<div></div>
  <script>
    const div = document.querySelector('div')
    div.style.width

    // 获取宽高 
    // 获取页面宽高使用clientWidth
    // clientWidth:包含:内容宽 + padding
    console.log(div.clientWidth,div.clientHeight)

    // offsetWidth:包含:内容宽 + padding + border
    // 获取元素宽高:offsetWidth
    console.log(div.offsetWidth,div.offsetHeight)

  </script>

获取位置

属性名:offsetLeft和offsetTop

使用场景:获取元素距离自己定位父级元素的左、上距离,参照定位元素的位置距离

方法名:getBoundingClientRect

语法:element.getBoundingClientRect()

返回值:元素的大小及其相对于视口的位置

注意:

  1. offsetLeft和offsetTop 注意是只读属性,只能获取,不能设置
  2. offsetLeft和offsetTop 以带有定位的父级为参考坐标,如果上级中都没有定位则以文档左上角 为准

元素尺寸与位置属性

标签:function,进阶,DOM,元素,事件,addEventListener,div,document
来源: https://www.cnblogs.com/yyshow/p/16268531.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有