将html代码转换为dom,将HTML字符转换为DOM节点并动态添加到文档中

将HTML字符转换为DOM节点并动态添加到文档中

将字符串动态转换为DOM节点,在开发中经常遇到,尤其在模板引擎中更是不可或缺的技术。

字符串转换为DOM节点本身并不难,本篇文章主要涉及两个主题:

1 字符串转换为HTML DOM节点的基本方法及性能测试

2 动态生成的DOM节点添加到文档中的方法及性能测试

本文的示例: 有如下代码段

Document

复制代码

任务是编写一个JavaScript函数,接收一个文本内容,动态生成一个包含该文本的div,返回该Node。

1.1 动态创建Node

1.1.1 innerHTML

第一种方法,我们使用document.createElement方法创建新的元素,然后利用innerHTML将字符串注入进去,最后返回firstChild,得到动态创建的Node。

const template = `

${txt}
`;

let tempNode = document.createElement('div');

tempNode.innerHTML = template;

return tempNode.firstChild;

}

const container = document.getElementById('container');

container.appendChild(createNode('hello'));

复制代码

下面我们看第二种方法

1.1.2 DOMParser

DOMParser 实例的parseFromString方法可以用来直接将字符串转换为document 文档对象。有了document之后,我们就可以利用各种DOM Api来进行操作了。

function createDocument(txt){

const template = `

${txt}
`;

let doc = new DOMParser().parseFromString(template, 'text/html');

let div = doc.querySelector('.child');

return div;

}

const container = document.getElementById('container');

container.appendChild(createDocument('hello'));

复制代码

1.1.2 DocumentFragment

DocumentFragment 对象表示一个没有父级文件的最小文档对象。它被当做一个轻量版的 Document 使用,用于存储已排好版的或尚未打理好格式的XML片段。最大的区别是因为DocumentFragment不是真实DOM树的一部分,它的变化不会引起DOM树的重新渲染的操作(reflow) ,且不会导致性能等问题。

利用document.createRange().createContextualFragment方法,我们可以直接将字符串转化为DocumentFragment对象。

function createDocumentFragment(txt){

const template = `

${txt}
`;

let frag = document.createRange().createContextualFragment(template);

return frag;

}

const container = document.getElementById('container');

container.appendChild(createDocumentFragment('hello'));

复制代码

这里要注意的是我们直接将生成的DocumentFragment对象插入到目标节点中,这会将其所有自己点插入到目标节点中,不包含自身。我们也可以使用

frag.firstChild

复制代码

来获取生成的div。

1.1.3 性能测试

下面我们来简单比对下上面三种方法的性能,只是测试生成单个节点,在实际使用中并不一定有实际意义。

先测试createNode。

function createNode(txt){

const template = `

${txt}
`;

let start = Date.now();

for (let i = 0; i < 1000000; i++) {

let tempNode = document.createElement('div');

tempNode.innerHTML = template;

let node = tempNode.firstChild;

}

console.log(Date.now() - start);

}

createNode('hello');

复制代码

测试100万个Node生成,用时 6322。

再来测试createDocument。

function createDocument(txt){

const template = `

${txt}
`;

let start = Date.now();

for (let i = 0; i < 1000000; i++) {

let doc = new DOMParser().parseFromString(template, 'text/html');

let div = doc.firstChild;

}

console.log(Date.now() - start);

}

createDocument('hello');

复制代码

测试100万个Node生成,用时 55188。

最后来测试createDocumentFragment.

function createDocumentFragment(txt){

const template = `

${txt}
`;

let start = Date.now();

for (let i = 0; i < 1000000; i++) {

let frag = document.createRange().createContextualFragment(template);

}

console.log(Date.now() - start);

}

createDocumentFragment();

复制代码

测试100万个Node生成,用时 6210。

createDocumentFragment方法和createNode方法,在这轮测试中不相上下。下面我们看看将生成的DOM元素动态添加到文档中的方法。

1.2.0 批量添加节点

被动态创建出来的节点大多数情况都是要添加到文档中,显示出来的。下面我们来介绍并对比几种常用的方案。

下面我们批量添加的方法都采用createDocumentFragment方法。

1.2.1 直接append

直接append方法,就是生成一个节点就添加到文档中,当然这会引起布局变化,被普遍认为是性能最差的方法。

const template = "

hello
";

function createDocumentFragment(){

let frag = document.createRange().createContextualFragment(template);

return frag;

}

// createDocumentFragment();

const container = document.getElementById('container');

let start = Date.now();

for (let i = 0; i < 100000; i++) {

container.appendChild(createDocumentFragment());

}

console.log(Date.now() - start);

复制代码

上面的代码我们测算动态添加10万个节点。结果如下:

b6e58ceb8ec69f5d8bcc5f9644db7628.png

测试1000个节点耗时20毫秒,测试10000个节点耗时10001毫秒,测试100000个节点耗时46549毫秒。

1.2.2 DocumentFragment

上面我们已经介绍过DocumentFragment了,利用它转换字符串。下面我们利用该对象来作为临时容器,一次性添加多个节点。

利用document.createDocumentFragment()方法可以创建一个空的DocumentFragment对象。

const template = "

hello
";

function createDocumentFragment(){

let frag = document.createRange().createContextualFragment(template);

return frag;

}

// createDocumentFragment();

const container = document.getElementById('container');

let fragContainer = document.createDocumentFragment();

let start = Date.now();

for (let i = 0; i < 1000; i++) {

fragContainer.appendChild(createDocumentFragment());

}

container.appendChild(fragContainer);

console.log(Date.now() - start);

复制代码

测试1000个节点耗时25毫秒,10000个节点耗时2877毫秒,100000个节点浏览器卡死。

1.3 小结

简单了介绍了几种方法,并没有什么技术含量。但是从动态添加节点来看,网上说的DocumentFragment方法性能远远好于直接append的说法在我的测试场景中并不成立。

DocumentFragment正确的应用场景应该是作为虚拟DOM容器,在频繁修改查询但是并不需要直接渲染的场景中。

更多精彩内容,请关注 微信订阅号“玄说前端”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338578.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python 的csr_python的高级数组之稀疏矩阵

稀疏矩阵的定义&#xff1a;具有少量非零项的矩阵(在矩阵中&#xff0c;若数值0的元素数目远多于非0元素的数目&#xff0c;并且非0元素分布没有规律时&#xff0c;)则称该矩阵为稀疏矩阵&#xff1b;相反&#xff0c;为稠密矩阵。非零元素的总数比上矩阵所有元素的总数为矩阵的…

通过Spring集成进行消息处理

Spring Integration提供了Spring框架的扩展&#xff0c;以支持著名的企业集成模式。 它在基于Spring的应用程序中启用轻量级消息传递&#xff0c;并支持与外部系统的集成。 Spring Integration的最重要目标之一是为构建可维护且可测试的企业集成解决方案提供一个简单的模型。 …

鸿蒙系统多会发布,华为官宣鸿蒙系统将发布,还将发布多款新品

华为今日官宣&#xff0c;6月2日20&#xff1a;00&#xff0c;将举行鸿蒙操作系统及华为全场景新品发布会。【1、鸿蒙OS2.0】本次发布会的重点将是推出华为今年的重点战略产品——鸿蒙系统。届时鸿蒙OS2.0正式版将陆续推送给手机用户。5月中旬时华为就先行推送了一波鸿蒙OS开发…

C语言结构体字节对齐

默认字节对齐C语言结构体字节对齐是老生常谈的问题了&#xff0c;也是高频面试题&#xff0c;现在我们来深入研究这个问题&#xff0c;彻底弄懂到底是怎么回事&#xff0c;给你一个结构体定义和平台机器位数就能手动计算出结构体占用字节数&#xff0c;现在我们不使用宏#pragma…

shell shocked伴奏版_Shell Shocked

【游戏简介】Shell Shocked是一款全新卡牌对战题材的策略类手机游戏。游戏有着丰富的卡牌种类&#xff0c;极具策略性的玩法。游戏中玩家可以将进行真人游戏对战&#xff0c;随机抽取卡牌对战。玩家必须采取适合的策略&#xff0c;才有可能赢取游戏。 游戏操作简单&#xff0c;…

meetup_使用RxNetty访问Meetup的流API

meetup本文将涉及多个主题&#xff1a;响应式编程&#xff0c;HTTP&#xff0c;解析JSON以及与社交API集成。 完全在一个用例中&#xff1a;我们将通过非夸张的RxNetty库实时加载和处理新的metup.com事件&#xff0c;结合Netty框架的强大功能和RxJava库的灵活性。 Meetup提供了…

html约束验证的例子,HTML5利用约束验证API来检查表单的输入数据的代码实例

HTML5对于表单有着极大程度的优化&#xff0c;无论是语义&#xff0c;小部件&#xff0c;还是数据格式的验证。我猜你肯定会以浏览器兼容作为借口不愿意使用这些“新功能”&#xff0c;但这绝不应该成为使你停滞不前的原因&#xff0c;况且还有像Modernizr和ployfill这样的工具…

C语言经典题(1)

输入某年某月某日&#xff0c;判断这一天是这一年的第几天&#xff1f;程序分析&#xff1a;以3月5日为例&#xff0c;应该先把前两个月的加起来&#xff0c;然后再加上5天即本年的第几天&#xff0c;特殊情况&#xff0c;闰年且输入月份大于3时需考虑多加一天#include int mai…

jpg图片使用pil的resize后_如何使用PIL调整图像大小并保持其纵横比?

是否有一种显而易见的方法可以解决这个问题&#xff1f; 我只是想制作缩略图。#1楼PIL已经可以选择裁剪图像img ImageOps.fit(img, size, Image.ANTIALIAS)#2楼我丑陋的例子。函数获取文件如&#xff1a;“pic [0-9a-z]。[extension]”&#xff0c;将它们调整为120x120&#x…

openshift_OpenShift上的Java EE工作流(技术提示#64)

openshift该网络研讨会展示了如何使用WildFly &#xff0c; JBoss Tools &#xff0c; Forge &#xff0c; Arquillian和OpenShift在OpenShift上创建Java EE工作流。 具体来说&#xff0c;它谈论&#xff1a; 如何使用JBoss Developer Studio轻松开发Java EE应用程序并将其直接…

C语言面试-指针和引用的使用场景?

先解决两个疑问◆ 指针和引用的不同之处是什么&#xff1f;◆ 何时用用指针&#xff1f;何时用引用&#xff1f;指针和引用的不同之处看如下代码&#xff1a;指针是用来表示内存地址的&#xff0c;而指针这个整数正是被指向的变量地址。而引用就是给变量重新起了一个名字&#…

排序算法html,排序算法总结.html

排序算法总结 | borens blog排序算法总结borens blog首页所有文章关于作者排序算法总结Apr 6, 2018| 技术人生| 阅读排序,顾名思义,将数据按照某种规则排列起来.这种规则可以是根据基本的数值大小排序,也可以是通过字符串长度比较来排序,又或者是优先根据两个字符串的第一个不…

win10商店下载位置_win10应用商店下载的东西在哪

win10应用商店下载的东西在哪&#xff1f;我们都知道&#xff0c;微软从win8开始&#xff0c;就推出了应用商店&#xff0c;到现在的win10&#xff0c;还是一样。现在的win10应用商店里的东西也越来越丰富了。但是有些win10新用户朋友们在win10应用商店下载了东西&#xff0c;准…

异步http 超时_具有CompletableFuture的异步超时

异步http 超时有一天&#xff0c;我重写了执行不佳的多线程代码&#xff0c;该代码在Future.get()某个时刻被阻塞&#xff1a; public void serve() throws InterruptedException, ExecutionException, TimeoutException {final Future<Response> responseFuture async…

C语言指针变量与一维数组

数组元素之间的地址是相连的&#xff1b;变量地址绝对不是相连的&#xff0c;如果找到规律那也只是一个偶然的&#xff0c;不是必然的&#xff1b;1. 指针变量和一位数组下面对指针数组进行分析&#xff0c;index(小标是从0开始)&#xff0c;array数组是int类型&#xff0c;每一…

天干地支计算公式_高大上:天干地支计算方法

天干地支是我国古代计算年月日的重要依据&#xff0c;作为现代人的我们&#xff0c;有必要去了解一下&#xff0c;他们&#xff0c;以备不时之需。首先介绍一下&#xff0c;天干和地支。共有十天干和十二地支。十天干&#xff1a;甲(jiǎ)、乙(yǐ)、丙(bǐng)、丁(dīng)、戊(…

input发送a.jax_JAX-RS 2.0:服务器端处理管道

input发送a.jax这篇文章的灵感来自JAX-RS 2.0规范文档 &#xff08;附录C&#xff09;中的Processing Pipeline部分。 我喜欢它的原因在于它提供了JAX-RS中所有模块的漂亮快照-以准备好吞咽的胶囊形式&#xff01; 礼貌– JAX-RS 2.0规范文档 因此&#xff0c;我想到了使用此…

html 登录失败,qq音乐登录失败 QQ音乐总是显示登录失败是怎么回事

urlproc.exe是什么进程?没见过&#xff0c;请前辈们指点&#xff1f;造成QQ音乐登录不上现象的原因有如下三种可能&#xff1a; 一、木马病毒对QQ音乐的必要组件或文件进行破坏&#xff0c;导致QQ音乐登录失败&#xff0c;登陆不上的情况发生。 二、Windows系统防火墙(或其他安…

C 常对象成员

C 常对象成员在C 中&#xff0c;可以将对象的成员声明为const&#xff0c;包括常数据成员和常成员函数C 常数据成员 常数据成员的作用与一般常变量相似&#xff0c;用关键字const来声明常数据成员。常数据成员的值是不能改变的&#xff0c;只能通过构造函数的参数初始化表对常数…

python gitlab_Python Gitlab Api 使用方法

简述公司使用gitlab 来托管代码,日常代码merge request 以及其他管理是交给测试&#xff0c;鉴于操作需经常打开网页,重复且繁琐,所以交给Python 管理。安装pip install python-gitlab环境: py3DEMO# -*- coding: utf-8 -*-__Author__ "xiewm"__Date__ 2017/12/26 …