时间对象 与 DOM事件(高级)

100 阅读4分钟

时间对象 与 DOM事件(高级)

1. 时间对象

  • 因为事件对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式

1649854567634.png

语法:

<script>
        let h1 = document.querySelector('h1')
        
        // 用函数封装使用
        setInterval(function () {
            let date = new Date()
			//  时间对象
          let fullyear = date.getFullYear()
          let month = date.getMonth() + 1
          let date1 = date.getDate()
          let hours = date.getHours()
          let minutes = date.getMinutes()
          let seconds = date.getSeconds()

          // 设置时间不足10 的时候拼接 字符串'0'
           month = month < 10 ? '0' + month : month
           date1 = date1 < 10 ? '0' + date1 : date1
           hours = hours < 10 ? '0' + hours : hours
           minutes = minutes < 10 ? '0' + minutes : minutes
           seconds = seconds < 10 ? '0' + seconds : seconds
          
          h1.innerText = `${fullyear}-${month}-${date1} ${hours}:${minutes}:${seconds}`;
        },1000)
    </script>

① 时间戳

  • 时间戳 : 是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式
  • 重点记住 +new Date() 因为可以返回当前时间戳或者指定的时间戳

获取方法

<script>
        //  三种方式  获取时间戳
        let date = new Date();
        // console.log(date.getTime());   // 方式一
        
        // console.log(+(new Date()));  // 方式二  只要日期对象 可以使用 + 将整个对象 转成 时间戳

        console.log(Date.now());    // 方式三

        // 用来快速生成一个不会重复的数字 * 随机数
    </script>

2. 重绘和回流

1649855397604.png

① 重绘和回流(重排)

回流(重排): 当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过程称为 回流。

  • 重绘:

    由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、outline等), 称为重绘。

  • 重绘不一定引起回流,而回流一定会引起重绘。

  • 会导致回流(重排)的操作:

    ​ 》页面的首次刷新

    ​ 》浏览器的窗口大小发生改变

    ​ 》元素的大小或位置发生改变

    ​ 》改变字体的大小

    ​ 》内容的变化(如:input框的输入,图片的大小)

    ​ 》激活css伪类 (如::hover)

    ​ 》脚本操作DOM(添加或者删除可见的DOM元素)

    简单理解影响到布局了,就会有回流

1649855844737.png

3. DOM事件(高级)

(1) 事件对象

① 事件获取对象
  • 事件对象:

    ​ 》也是个对象,这个对象里有事件触发时的相关信息

    ​ 》例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息

  • 如何获取

    ​ 》在事件绑定的回调函数的第一个参数就是事件对象

1649856434170.png

<body>
        <button>点击按钮</button>

    <script>
        const btn = document.querySelector('button')

        btn.addEventListener('click', function(event){
            console.log(event);// 存放事件触发的一瞬间的信息 - 鼠标位置信息
        })
    </script>
</body>
② 事件对象常用属性

1649858008310.png

(2). 事件流

① 事件流与两个阶段说明
  • 事件流 指的是事件完整执行过程中的流动路径
  • 说明:假设页面里有个div,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段
  • 简单来说:捕获阶段是 从父到子 冒泡阶段是从子到父

1649858248950.png

② 事件捕获和事件冒泡
  • 事件冒泡概念:

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

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

  • 事件冒泡是默认存在的

     <script>
            
            const a = document.querySelector('.a')
            a.addEventListener('click', function () {
                console.log('a');
            },false)
    
            const b = document.querySelector('.b')
            b.addEventListener('click', function () {
                console.log('b');
            },false)
    
            const c = document.querySelector('.c')
            c.addEventListener('click', function () {
                console.log('c');
            },false)
    
            // true 冒泡  false 捕获  ( 默认值是 false )
        </script>
    

1649858466227.png

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

  • 事件捕获需要写对应代码才能看到效果

1649858529871.png

  • 说明:

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

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

    ​ 》若是用 L0 事件监听,则只有冒泡阶段,没有捕获

③ 阻止事件流动
  • 因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素
  • 若想把事件就限制在当前元素内,就需要阻止事件流动
  • 阻止事件流动需要拿到事件对象
  • 此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效
  • 语法:

1649858755213.png

  • 鼠标经过事件:

    ​ 》mouseover 和 mouseout 会有冒泡效果

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

  • 阻止默认行为,比如链接点击不跳转,表单域的不提交

    语法:

1649859810981.png

  • 两种注册事件的区别:

  • 传统on注册(L0)

    ​ 》同一个对象,后面注册的事件会覆盖前面注册(同一个事件)

    ​ 》直接使用null覆盖偶就可以实现事件的解绑

    ​ 》都是冒泡阶段执行的

  • 事件监听注册(L2)

    ​ 》语法: addEventListener(事件类型, 事件处理函数, 是否使用捕获)

    ​ 》后面注册的事件不会覆盖前面注册的事件(同一个事件)

    ​ 》可以通过第三个参数去确定是在冒泡或者捕获阶段执行

    ​ 》必须使用removeEventListener(事件类型, 事件处理函数, 获取捕获或者冒泡阶段)

    ​ 》匿名函数无法被解绑

(3) 事件委托

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

  • 总结:

    ​ 》优点:给父级元素加事件(可以提高性能) ​ 》原理:事件委托其实是利用事件冒泡的特点, 给父元素添加事件,子元素可以触发 ​ 》实现:事件对象.target 可以获得真正触发事件的元素

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            * {
                padding: 0;
                margin: 0;
    
            }
    
            ul {
                width: 500px;
                background-color: aqua;
                padding: 50px;
            }
    
            li {
                background-color: yellow;
                height: 50px;
            }
    
            a {
                background-color: sandybrown;
            }
        </style>
    </head>
    <body>
        <ul>
            <li><a href="#">1</a></li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
          </ul>
        
        <script>
       
    
            // 事件委托
            const ul = document.querySelector('ul')
            ul.addEventListener('click', function (event) {
    
                event.target.style.backgroundColor = 'red' // 不够完美
                // event.target 你当前点击的是哪个标签(点击最深最底层的那个标签即可)
            // console.log(event.target);// 获取到被点击的li标签 
            })
    
        </script>
    </body>
    </html>