持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
前言
JavaScript是基础并且是非常重要的一部分,现在项目基本都靠框架开发,很多原生方法得不到使用就会慢慢忘记,所以借着6月更文好好复习一下基础知识,今天讲讲DOM事件流。
文档碎片节点
当我们去大量去操作DOM的时候,势必会引起性能问题,因为页面会进行重新渲染,造成重绘重排,而重绘重排是DOM编程中耗能的主要原因之一,而我们需要利用文档碎片节点的方式来减少页面的重绘重排。
关于重排(回流)与重绘的基本介绍
重排(回流)
- 当render tree中的一部分或者是全部,因为元素的尺寸、布局、隐藏等等改变引起页面的重新渲染,这个过程称作为重排
重绘
- 当render tree(渲染树)中更新的属性只会影响元素的外观、风格,不会影响元素的布局的时候,浏览器需要重新绘制当前元素的样式,被称作为重绘。 重绘不会引起重排,但重排一定会引起重绘,一个元素的重排通常会带来一系列的反应,甚至触发整个文档 的重排和重绘,性能代价是高昂的
关于文档碎片节点的具体使用
<body>
<ul class="box"></ul>
</body>
<script>
var oBox = document.querySelector('.box')
oBox.onclick = function(){
//首先创建文档碎片节点
var oFrag = document.createDocumentFragment();
//比如说要插入很多元素
for(var i = 0; i < 100; i++){
var newLi = document = createElement('li');
newLi.innerHtml = 'text';
//保存在文档碎片节点里
oFrag.appendChild(newLi)
}
//一次性加入,只渲染一次页面
oBox.appendChild(oFrag)
}
</script>
事件流(事件模型、事件机制)
多个节点对象对同一个事件的响应顺序,被称作为事件流
谈谈w3c事件流
- 执行捕获阶段:网景浏览器提出,事件由最不精确的对象(document)依次执行到最精确的目标元素(target)
- 执行冒泡阶段:IE浏览器提出,事件由最精确的目标元素(target) 依次执行到 最不精确的对象(document)
- 事件根据自身是冒泡还是捕获,决定自身在哪一个阶段执行
事件处理函数
- w3c提供了一个事件处理函数 addEventListener()也就是DOM2级事件处理函数 专门用来处理事件
- 参数1:事件名称 (没有on)
- 参数2:事件函数
- 参数3:布尔值,代表冒泡(false)或捕获(true)时候触发,默认false
- 特点
- 可以给同一个元素绑定同一个事件多次
- 可以控制冒泡和捕获
- 删除事件:使用removeEventListener()方法
- 参数1:移除的事件名
- 参数2:移除当前事件名的哪一个事件函数
- 参数3:移除的当前事件是冒泡阶段还是捕获阶段 是一个布尔值
- 使用场景
- 对同一个元素绑定同一个事件多次 不希望被覆盖
- 可以控制捕获或者冒泡
- DOM2级事件 只能通过事件处理函数绑定(DOMContentLoaded)
通过一个小demo来熟悉一下DOM2级事件处理函数
<body>
<button class="btn">取消点击</button>
<div class="text">点我弹出信息</div>
</body>
<script>
var oBtn = document.querySelector('.btn')
var oText = document.querySelector('.text')
//弹出信息事件函数
function fn(){
alert('我弹出来了')
}
//点击弹出信息
oText.addEventListener('click',fn,false)
//取消点击事件
oBtn.onclick = function(){
oText.removeEventListener('click',fn,false)
}
</script>
事件对象
event
- 当事件发生的时候,有一个对象保存的是当前事件所有相关的信息,这个对象被称作为event事件对象
- 获取:function(event){} || window.event 阻止默认事件
- event.preventDefault()
- 阻止传播:即冒泡或捕获 event.stopPropagation
事件委托
事件委托属于一个小优化点,其实就是利用冒泡原理把子元素需要触发的绑定在父元素上,通过event事件对象的target属性,获取当前点击的精确元素,减少了绑定次数,提交效率,而且未来在父元素下面的子元素也不需要重新绑定,可以直接操作。
通过一个demo演示一下事件委托
<body>
<button class="btn">添加</button>
<ul class="box">
<li>1</li>
<li>2</li>
</ul>
</body>
<script>
var oBtn = document.querySelector('.btn')
var oBox = document.querySelector('.box')
//使用事件委托到父元素上,通过event.target来找到对应的子元素,还可以给未来添加的li添加颜色
oBox.onclick = function (event){
if(event.target.nodeName.toLowerCase()==='li'){
event.target.style.background = 'pink'
}
}
oBtn.onclick = function(){
var newLi = document.createElement('li')
newLi.textContent = '新添加的li'
oBox.appendChild(newLi)
}
</script>
好了,以上就是本篇文章的分享,感谢阅读!