时间对象 与 DOM事件(高级)
1. 时间对象
- 因为事件对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式
语法:
<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. 重绘和回流
① 重绘和回流(重排)
回流(重排): 当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过程称为 回流。
-
重绘:
由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、outline等), 称为重绘。
-
重绘不一定引起回流,而回流一定会引起重绘。
-
会导致回流(重排)的操作:
》页面的首次刷新
》浏览器的窗口大小发生改变
》元素的大小或位置发生改变
》改变字体的大小
》内容的变化(如:input框的输入,图片的大小)
》激活css伪类 (如::hover)
》脚本操作DOM(添加或者删除可见的DOM元素)
简单理解影响到布局了,就会有回流
3. DOM事件(高级)
(1) 事件对象
① 事件获取对象
-
事件对象:
》也是个对象,这个对象里有事件触发时的相关信息
》例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息
-
如何获取
》在事件绑定的回调函数的第一个参数就是事件对象
<body>
<button>点击按钮</button>
<script>
const btn = document.querySelector('button')
btn.addEventListener('click', function(event){
console.log(event);// 存放事件触发的一瞬间的信息 - 鼠标位置信息
})
</script>
</body>
② 事件对象常用属性
(2). 事件流
① 事件流与两个阶段说明
- 事件流 指的是事件完整执行过程中的流动路径
- 说明:假设页面里有个div,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段
- 简单来说:捕获阶段是 从父到子 冒泡阶段是从子到父
② 事件捕获和事件冒泡
-
事件冒泡概念:
》当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡
-
简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件
-
事件冒泡是默认存在的
<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>
-
事件捕获概念: 从DOM的根元素开始去执行对应的事件 (从外到里)
-
事件捕获需要写对应代码才能看到效果
-
说明:
》addEventListener第三个参数传入true代表是捕获阶段触发(很少使用)
》若传入false代表冒泡阶段触发,默认就是false
》若是用 L0 事件监听,则只有冒泡阶段,没有捕获
③ 阻止事件流动
- 因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素
- 若想把事件就限制在当前元素内,就需要阻止事件流动
- 阻止事件流动需要拿到事件对象
- 此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效
- 语法:
-
鼠标经过事件:
》mouseover 和 mouseout 会有冒泡效果
》mouseenter 和 mouseleave 没有冒泡效果(推荐)
-
阻止默认行为,比如链接点击不跳转,表单域的不提交
语法:
-
两种注册事件的区别:
-
传统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>