首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >DOM操作

DOM操作

作者头像
奋飛
发布于 2019-08-15 08:19:42
发布于 2019-08-15 08:19:42
1.1K0
举报
文章被收录于专栏:Super 前端Super 前端

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://ligang.blog.csdn.net/article/details/71053133

​ 页面上有个空的无序列表节点,用<ul></ul> 表示,通过JavaScript动态往列表中插入 3 个<li>,每个列表项的文本内容是列表项的插入顺序,取值 1, 2, 3;同时绑定click事件,单击依次输出1,2,3。

代码语言:javascript
AI代码解释
复制
<ul class="js-container">
    <!-- 动态添加内容 -->
</ul>

动态添加li

代码语言:javascript
AI代码解释
复制
var containerDom = document.querySelector('.js-container'),
    itemDom = null;

for(let i = 1; i <= 3; i++) {
    itemDom = document.createElement("li");
    itemDom.innerText = i;
    containerDom.appendChild(itemDom);
}

绑定事件

代码语言:javascript
AI代码解释
复制
var containerDom = document.querySelector('.js-container'),
    itemDom = null;

for(let i = 1; i <= 3; i++) {
    itemDom = document.createElement("li");
    itemDom.innerText = i;
    itemDom[i].addEventListener('click', function() {
        alert(i); // alert(this.innerText);
    });
    containerDom.appendChild(itemDom);
}

需要注意: 上述使用let局部作用域(使用闭包同样可以实现)!绑定事件使用addEventListener,而没有使用内联事件onclick。是因为内联事件是作为元素属性保存起来的,这些属性可以被覆盖,所以如果为同一个事件绑定了多个处理程序,那么最后一个处理程序会覆盖之前的。

增大数据量

​ 如果将li的数量改为500,5000甚至更大呢?页面必然会出现卡顿或者直接卡死。

事件代理,减少事件数量

代码语言:javascript
AI代码解释
复制
var containerDom = document.querySelector('.js-container'),
    itemDom = null;

for(let i = 1; i <= 500; i++) {
    itemDom = document.createElement("li");
    itemDom.innerText = i;
    containerDom.appendChild(itemDom);
}

// 事件代理
containerDom.addEventListener('click', function(e){
    const target = e.target;
    if (target.tagName === 'LI') {
        alert(target.innerHTML);
    }
});

DocumentFragement可以减少DOM操作

​ 接口表示的是没有父节点的最小的文档对象。它被当做一个轻量版本的 Document 使用,用于存储已排好版的或尚未打理好格式的XML片段。可以使用document.createDocumentFragment方法或者构造函数来创建一个空的 DocumentFragment.

​ DocumentFragement通常用来创建一个文档片段,然后将创建的DOM元素插入到文档片段中,最后把文档片段插入到DOM树中。在DOM树中,文档片段会被替换为它所有的子元素。因为文档片段存在于内存中,并不在DOM树中,所以将子元素插入到文档片段时不会引起页面重绘(reflow)(对元素位置和几何上的计算)。因此,使用文档片段DocumentFragement通常会起到优化性能的作用。

代码语言:javascript
AI代码解释
复制
var containerDom = document.querySelector('.js-container'),
    contentFragment = document.createDocumentFragment(),
    itemDom = null;

// 先将li添加到contentFragment,已减少dom操作
for(let i = 1; i <= 500; i++) {
    itemDom = document.createElement("li");
    itemDom.innerText = i;
    contentFragment.appendChild(itemDom);
}
containerDom.appendChild(contentFragment);

// 事件代理
containerDom.addEventListener('click', function(e){
    const target = e.target;
    if (target.tagName === 'LI') {
        alert(target.innerHTML);
    }
});

分批处理,requestAnimationFrame平滑过渡

创建动画时,大家经常会想到使用setTimeoutsetInterval。使用上述方式有这样几个问题:

  • 动画区域或者页面已被隐藏,setTimeoutsetInterval仍被执行;
  • 大多数计算机显示器以60Hz的速率刷新,这基本上意味着每秒重新绘制60次。为了得到最平滑的动画,需要设置最佳间隔是1000ms / 60或约17ms,但这不能覆盖全部浏览器;
  • 延迟毫秒数并不意味着该毫秒后被执行,仅表示其进行排队。如果UI线程很忙,可能会处理用户操作,那么该代码将不会立即执行;

window.requestAnimationFrame(callback) 方法告诉浏览器您希望执行动画,并请求浏览器调用指定的函数在下一次重绘之前更新动画。该方法将在重绘之前调用的回调作为参数。window.cancelAnimationFrame() 来取消这个回调函数。

代码语言:javascript
AI代码解释
复制
const containerDom = document.querySelector('.js-container');

const total = 5000,   // 5000个li
    batchSize = 50,   // 每一个批次执行50个
    batchCount = Math.ceil(total / batchSize); // 批次数
let batchDone = 0;  // 已经完成的批处理个数

/**
 * 批次插入li
 */
function appendItems() {
    let contentFragment = document.createDocumentFragment(),
        itemDom = null;
    for(let i = 1; i <= batchSize; i++) {
        itemDom = document.createElement("li");
        itemDom.innerText = (batchDone * batchSize) + i;
        contentFragment.appendChild(itemDom);
    }
    containerDom.appendChild(contentFragment);
    batchDone++;
    // 调用下一批次
    doBatchAppend();
}

/**
 * 平滑插入各个批次
 */
function doBatchAppend() {
    if (batchDone < batchCount) {
        // 无需设置时间
        window.requestAnimationFrame(appendItems);
    }
}

doBatchAppend();

// 绑定事件
containerDom.addEventListener('click', function(e){
    const target = e.target;
    if (target.tagName === 'LI') {
        alert(target.innerHTML);
    }
});

注意: requestAnimationFrame()存在一定的兼容性问题

代码语言:javascript
AI代码解释
复制
(function() {
    if (window.requestAnimationFrame) {
        return;
    } else {
        var lastTime = 0;
        var vendors = ['ms', 'moz', 'webkit', 'o'];
        for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
            window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
            window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
                     || window[vendors[x]+'CancelRequestAnimationFrame'];
        }
        // 使用setTimeout模拟实现
        if (!window.requestAnimationFrame){
            window.requestAnimationFrame = function(callback, element) {
                var currTime = new Date().getTime();
                var timeToCall = Math.max(0, 16 - (currTime - lastTime));
                var id = window.setTimeout(function() { 
                  callback(currTime + timeToCall); 
                }, timeToCall);
                lastTime = currTime + timeToCall;
                return id;
            };
            window.cancelAnimationFrame = function(id) {
                clearTimeout(id);
            };
        }
    }
}());

参考地址: http://creativejs.com/resources/requestanimationframe/ https://www.nczonline.net/blog/2011/05/03/better-javascript-animations-with-requestanimationframe/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017年05月01日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
使用 requestAnimationFrame 替代 throttle 优化页面性能
前面的文章《函数防抖(debounce)和节流(throttle)在H5编辑器项目中的应用》中讲过,对于 mousemove, scroll 这类事件,一般的解决方法是使用 throttle 节流函数,但是节流函数解决这类问题并不完美,存在两点缺陷:
CS逍遥剑仙
2020/04/12
2.6K0
requestAnimationFrame简介
当我们写window.requestAnimationFrame(回调函数)时,浏览器会在下次重绘前执行回调函数。
前端GoGoGo
2018/08/27
9470
requestAnimationFrame简介
Vue 折腾记 - (6) 写一个不大靠谱的backToTop组件
返回顶部这个功能用jq实现,好容易实现,一个animate配合scrollTo就搞定了
CRPER
2018/08/28
6530
Vue 折腾记 - (6) 写一个不大靠谱的backToTop组件
DOM操作笔记
DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。
bamboo
2019/01/29
1.3K0
DOM操作笔记
干货满满!如何做好前端日志和异常监控的思考
在研发过程中,日志是非常重要的一环,它可以帮助我们快速定位问题,解决问题。在前端开发中,日志也是非常重要的一环,它可以帮助我们快速定位问题,解决问题。本文将介绍前端日志的规范和最佳实践。但是我们经常看到一些项目日志打得满天飞,但是到了真正定位问题的时候,发现日志并没有什么卵用。这是因为日志打得不规范,不规范的日志是没有意义的。所以我们需要规范日志的打印,才能让日志发挥最大的作用。
老码小张
2024/03/20
1.8K1
干货满满!如何做好前端日志和异常监控的思考
使用 requestAnimationFrame 实现动画
首先想到的是 setInterval/setTimeout,原理就是利用人眼的视觉残留和电脑屏幕的刷新,让元素以连贯平滑的方式逐步改变位置,最终实现动画的效果。
李振
2021/11/26
1.2K0
【新年气象】WordPress 主题添加花瓣飘落特效
第一步,将”hua.php””snowfall.js”文件上传到当前主题根目录hua文件夹中
小狐狸说事
2022/11/28
8700
什么是时间分片(Time Slicing)?
所以为了避免这种情况,我们可以使用两种方案,一种是Web Worker,另一种是时间切片(Time Slicing)。
陈大鱼头
2020/09/21
1.6K0
什么是时间分片(Time Slicing)?
JavaScript中的时间分片(Time Slicing)
当延迟超过100ms,用户就会察觉到轻微的延迟。所以为了避免这种情况,我们可以使用两种方案,一种是Web Worker,另一种是时间切片(Time Slicing)。
刘亦枫
2020/03/19
3.4K0
js动画效果_js动画函数
传统js动画实现一般使用setTimeout/setInterval等定时方式执行一个动画更新操作,但这种方式在使用中存在一些问题。
全栈程序员站长
2022/11/04
36.4K0
如何渲染几万条数据并不卡住界面?
如何在不卡住页面的情况下渲染数据,也就是说不能一次性将几万条 都渲染出来,而应该一次渲染部分 DOM,那么就可以通过 requestAnimationFrame 来 每 16 ms 刷新一次。
TimothyJia
2020/02/18
6840
如何渲染几万条数据并不卡住界面?
javascript之DOM操作
http://www.cnblogs.com/kissdodog/archive/2012/12/25/2833213.html
bear_fish
2018/09/19
6810
前端: 如何渲染十万条数据
最直接的方法就是直接渲染出来,但是这样的做法肯定是不可取的,因为直接渲染太耗性能了。
用户9914333
2022/07/22
3K0
2020已经过去五分之四了,你确定还不来了解一下JS的rAF?
不会吧,不会吧,现在都2020年了不会还真人有人不知道JS的rAF吧??? rAF 简介 rAF是requestAnimationFrame的简称; 我们先从字面意思上理解requestAnimati
Tz一号
2020/10/26
1.4K0
2020已经过去五分之四了,你确定还不来了解一下JS的rAF?
DOM操作
1.概述 1.1DOM DOM是JavaScript操作网页的接口,全称为“文档对象模型”(Document Object Model)。文档对象模型 (DOM) 是HTML和XML文档的编程接口。它给文档(结构树)提供了一个结构化的表述并且定义了一种方式—程序可以对结构树进行访问,以改变文档的结构,样式和内容。 浏览器会根据DOM模型,将结构化文档(比如HTML和XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构,都有规范的对外接口。所以,DOM可以理
小胖
2018/06/27
2.3K0
「前端进阶」高性能渲染十万条数据(时间分片)
在实际工作中,我们很少会遇到一次性需要向页面中插入大量数据的情况,但是为了丰富我们的知识体系,我们有必要了解并清楚当遇到大量数据时,如何才能在不卡主页面的情况下渲染数据,以及其中背后的原理。
ConardLi
2019/09/19
2.7K0
「前端进阶」高性能渲染十万条数据(时间分片)
一次加载1w条数据的最优解是什么?
如果你需要首屏快的话,要用分页,其中requestAnimationFrame分页更为优秀,因为这个api会是系统调用的,刷新时机和屏幕刷新保持一致。setTimeout则不能保证一致。
爱吃大橘
2022/12/27
5500
上海加油,程序员是这么看视频的
刷了一晚上PYQ,花了一点时间临时写了这个代码,以下是完整代码。 <!DOCTYPE html> <html> <head> <!-- 程序员:大帅老猿 --> <meta charset="utf-8"> <title>BadApple</title> <style type="text/css"> html,body{ margin: 0; padding: 0; } </style> <script type="text/javascript"> functio
大帅老猿
2022/06/06
2930
上海加油,程序员是这么看视频的
requestAnimationFrame实现单张图片无缝持续滚动
在很久以前,有写过一个使用 js 实现单张图片持续滚动图片的 代码,但那一版实现会持续操作DOM,向DOM中插入元素,性能较差,最近发现 requestAnimationFrame 通过 动画的方式实现图片滚动更加方便,遂重新实现了一版,效果更赞,性能更好。
蓓蕾心晴
2022/05/09
4.2K0
requestAnimationFrame实现单张图片无缝持续滚动
requestAnimationFrame
即不用手动设置执行间隔时间,而是根据 浏览器屏幕刷新次数 自动调整了,也就是说浏览器屏幕刷新多少次,它就执行多少次。
用户4396583
2024/07/17
3190
相关推荐
使用 requestAnimationFrame 替代 throttle 优化页面性能
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
首页
学习
活动
专区
圈层
工具
MCP广场
首页
学习
活动
专区
圈层
工具
MCP广场