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

前言

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

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

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

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

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

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>
<body>
 <div id='container'>
<!-- 动态添加div
 <div class='child'> XXX</div>
 -->
 </div>
</body>
</html>

任务是编写一个JavaScript函数,接收一个文本内容,动态生成一个包含该文本的div,返回该Node。下面话不多说了,来随着小编一起看看详细的介绍吧。

1.1 动态创建Node

1.1.1 innerHTML

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

 <script>
  function createNode(txt) {
   const template = `<div class='child'>${txt}</div>`;
   let tempNode = document.createElement('div');
   tempNode.innerHTML = template;
   return tempNode.firstChild;
  }
  const container = document.getElementById('container');
  container.appendChild(createNode('hello'));
 </script>

下面我们看第二种方法

1.1.2 DOMParser

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

 function createDocument(txt) {
   const template = `<div class='child'>${txt}</div>`;
   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 = `<div class='child'>${txt}</div>`;
   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 = `<div class='child'>${txt}</div>`;

   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 = `<div class='child'>${txt}</div>`;
   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 = `<div class='child'>${txt}</div>`;
   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 = "<div class='child'>hello</div>";

  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万个节点。结果如下:

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

1.2.2 DocumentFragment

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

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

    const template = "<div class='child'>hello</div>";

    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容器,在频繁修改查询但是并不需要直接渲染的场景中。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • JavaScript操作HTML DOM节点的基础教程

    因为 DOM 的存在,这使我们可以通过 JavaScript 来获取.创建.修改.或删除节点. NOTE:下面提供的例子中的 element 均为元素节点. 获取节点 父子关系 element.parentNode element.firstChild/element.lastChild element.childNodes/element.children 兄弟关系 element.previousSibling/element.nextSibling element.previousElem

  • javascript 获取HTML DOM父、子、临近节点

    在Web应用程序特别是Web2.0程序开发中,经常要获取页面中某个元素,然后更新该元素的样式.内容等.如何获取要更新的元素,是首先要解决的问题.令人欣慰的是,使用JavaScript获取节点的方法有很多种,这里简单做一下总结(以下方法在IE7和Firefox2.0.0.11测试通过): 1. 通过顶层document节点获取: (1) document.getElementById(elementId):该方法通过节点的ID,可以准确获得需要的元素,是比较简单快捷的方法.如果页面上含有多个相同i

  • 获取HTML DOM节点元素的方法的总结

    令人欣慰的是,使用JavaScript获取节点的方法有很多种,这里简单做一下总结(以下方法在IE7和Firefox2.0.0.11测试通过): 1. 通过顶层document节点获取: (1) document.getElementById(elementId):该方法通过节点的ID,可以准确获得需要的元素,是比较简单快捷的方法.如果页面上含有多个相同id的节点,那么只返回第一个节点. 如今,已经出现了如prototype.Mootools等多个JavaScript库,它们提供了更简便的方法:$

  • [js高手之路]HTML标签解释成DOM节点的实现方法

    最近在封装一个开源框架,已经写了500行, 已经具备jquery的大多数常用功能,后面还会扩展大量的工具函数和MVVM双向驱动等功能.跟jquery的使用方法完全一样,jquery的选择器,几乎都能支持,为什么说这事,跟这篇文章的主题有毛关系呢?因为这篇文章要讲的就是我在写框架过程中碰到的一个问题,封装jquery的after方法,支持DOM和html标签两种用法,html标签传参,我要把html解释成DOM结构,用DOM的方法插入. 首先,我们写个通用的html标签: <div onclick

  • 用于节点操作的API,颠覆原生操作HTML DOM节点的API

    第一次看到敏捷开发的定义,我就被敏捷开发迷住了.通俗来说,敏捷开发可以让我们用过的代码可以再次重用,因为是再次重用,所以相对安全,再次调试也没有第一次那么费心,省时省力.不断重用代码的过程中把存在的bug不断的修复,也因为不断的去重用, 这个模板变得起越来越独立,适用的情况越来越广范,最后在安全方面达到铜墙铁壁,在开发方面达到随心所欲,在维护方面达到从容面对. 敏捷开发的确是利害,但如何练就这种深奥的武功呢?就我自身的情况靠人传授武功是不可能了,因为公司就我一个做开发的,苦思幂想之后,决定从开源

  • Js 获取HTML DOM节点元素的方法小结

    如何获取要更新的元素,是首先要解决的问题.令人欣慰的是,使用JavaScript获取节点的方法有很多种,这里简单做一下总结(以下方法在IE7和Firefox2.0.0.11测试通过)1. 通过顶层document节点获取:          (1) document.getElementById(elementId) :该方法通过节点的ID,可以准确获得需要的元素,是比较简单快捷的方法.如果页面上含有多个相同id的节点,那么只返回第一个节点.             如今,已经出现了如proto

  • JavaScript DOM节点操作实例小结(新建,删除HTML元素)

    本文实例讲述了JavaScript DOM节点操作方法.分享给大家供大家参考,具体如下: 使用DOM可以新建HTML元素,也可以删除已有的HTML元素. (一)新建元素: <script> //创建新的 <p> 元素 var newEle=document.createElement("p"); //创建文本节点 var node=document.createTextNode("这是使用Javascript创建的新段落."); //将文本节

  • html dom节点操作(获取/修改/添加或删除)

    HTML DOM 是关于如何获取.修改.添加或删除 HTML 元素的标准.在 HTML DOM 中,所有事物都是节点.DOM 是被视为节点树的 HTML. 根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点: 整个文档是一个文档节点 每个 HTML 元素是元素节点 HTML 元素内的文本是文本节点 每个 HTML 属性是属性节点 注释是注释节点 HTML DOM 将 HTML 文档视作树结构.这种结构被称为节点树: HTML DOM Tree 实例 http://www

  • 如何将HTML字符转换为DOM节点并动态添加到文档中详解

    前言 将字符串动态转换为DOM节点,在开发中经常遇到,尤其在模板引擎中更是不可或缺的技术. 字符串转换为DOM节点本身并不难,本篇文章主要涉及两个主题: 1 字符串转换为HTML DOM节点的基本方法及性能测试 2 动态生成的DOM节点添加到文档中的方法及性能测试 本文的示例: 有如下代码段 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> &

  • javascript将DOM节点添加到文档的方法实例分析

    本文实例讲述了javascript将DOM节点添加到文档的方法.分享给大家供大家参考.具体如下: 这里对两种方法进行了比较:第一种:先创建所有节点,再添加到文档方式的运行时长:第二种:先向文档添加一个空容器,然后每创建一个节点,再添加到容器中方式的运行时长,从测试来看,第二种方法优于第一种! 运行效果如下图所示: 具体代码如下: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-eq

  • Java获取XML节点总结之读取XML文档节点的方法

    dom4j是Java的XML API,用来读写XML文件的.目前有很多场景中使用dom4j来读写xml的. 要使用dom4j开发,需要下载导入dom4j相应的jar文件. 官网下载:http://www.dom4j.org/dom4j-1.6.1/ github下载:http://dom4j.github.io/ 下载解压之后如图所示: 我们只需要把dom4j-1.6.1.jar文件构建到我们开发项目中就可以了. 下面就以Eclipse创建java项目的构建方法为例说明: 声明:本Java项目的

  • Kafka单节点伪分布式集群搭建实现过程详解

    Kafka集群搭建分为单节点的伪分布式集群和多节点的分布式集群两种,首先来看一下单节点伪分布式集群安装.单节点伪分布式集群是指集群由一台ZooKeeper服务器和一台Kafka broker服务器组成,如下图所示: 为了搭建单节点Kafka集群,需要依次安装如下软件:安装Java-->安装ZooKeeper-->安装Kafka. 一.安装Java 可以参考linux安装jdk,来进行安装 二.安装ZooKeeper 下载地址:https://www-us.apache.org/dist/zoo

  • JQuery创建DOM节点的方法

    本文实例讲述了JQuery创建DOM节点的方法.分享给大家供大家参考.具体分析如下: 用JQuery选择器能够快捷而轻松地查找到文档中的某个特定的元素节点,然后可以用attr()方法来获取元素的各种属性的值.但真正的DOM操作并非这么简单.在DOM操作中,常常需要动态创建HTML内容,使文档在浏览器里的呈现效果发生变化,并且达到各种各样的人机交互的目的. HTML DOM结构如下: <p class="nm_p" title="欢迎访问我们" >欢迎访问

  • jQuery学习之DOM节点的插入方法总结

    本文主要总结了jQuery中DOM节点的插入方法,以及各种方法的注意点,下面话不多说,来看看详细的介绍吧. 一.内部插入append()与appendTo() append:这个操作与对指定的元素执行原生的appendChild方法,将它们添加到文档中的情况类似. appendTo:实际上,使用这个方法是颠倒了常规的$(A).append(B)的操作,即不是把B追加到A中,而是把A追加到B中. append()和appendTo()两种方法功能相同,主要的不同是语法--内容和目标的位置不同,ap

  • 详解Javascript中DOM的范围

    前言 为了让开发人员更方便地控制页面,DOM定义了"范围"(range)接口.通过范围可以选择文档中的一个区域,而不必考虑节点的界限(选择在后台完成,对用户是不可见的).在常规的DOM操作不能更有效地修改文挡时,使用范围往往可以达到目的.本文将详细介绍DOM范围,下面来一起看看吧. 创建范围 Document类型中定义了createRange()方法.在兼容DOM的浏览器中,这个方法属于document对象.使用hasFeature()或者直接检测该方法,都可以确定浏览器是否支持范围

  • jQuery 中DOM 操作详解

    jQuery 中的 DOM 操作 DOM(Document Object Model-文档对象模型):一种与浏览器,平台, 语言无关的接口,使用该接口可以轻松地访问页面中所有的标准组件 DOM 操作的分类: DOM Core: DOM Core 并不专属于 JavaScript, 任何一种支持 DOM的程序设计语言都可以使用它. 它的用途并非仅限于处理网页,也可以用来处理任何一种是用标记语言编写出来的文档, 例如: XML HTML DOM: 使用 JavaScript和 DOM 为 HTML文

  • Javascript DOM的简介,节点和获取元素详解

    目录 DOM 节点 元素节点: 文本节点: 属性节点: 获取元素 getElementById() getElementsByTagName() getElementsByClassName() 总结: DOM 文档:DOM中的"D",当创建一个网页并把它加载到Web浏览器中时,它把编写的网页文档转换为一个文档对象. 对象:DOM中的"O",对象是一种自给自足的数据集合.与某个特定对象相关联的变量被称为这个对象的属性,只能通过某个特定对象去调用的函数被称为这个对象的

随机推荐