原生JavaScript DOM操作常见汇总

码界流光
• 阅读 1786

前言

最近在看JS性能优化方面,说到了createDocumentFragment()方法,对该方法有印象,但为了进一步了解,我还是重新查阅一遍,顺便把DOM操作也给总结一下。

创建新节点

  • createDocumentFragment()方法

该方法是用来创建一个虚拟的节点对象,或者说,是用来创建文档碎片节点。它可以包含各种类型的节点,在创建之初是空的。

DocumentFragment 不是真实 DOM 树的一部分,它的变化不会触发 DOM 树的重新渲染,且不会导致性能等问题。

当把一个DocumentFragment节点插入文档树时,插入的不是DocumentFragment自身,而是它的所有子孙节点,即插入的是括号里的节点。这个特性使得DocumentFragment成了占位符,暂时存放那些一次插入文档的节点。

  • createElement()方法

在 HTML 文档中,document.createElement() 方法用于创建一个由标签名称 tagName 指定的 HTML 元素

来看一个例子, 对于页面已存在的<ul id="ul"></ul>元素,我们想往里面添加li标签

var ul = document.getElementById("ul");
for (var i = 0; i < 50; i++) {
    var li = document.createElement("li");
    li.innerHTML = "index: " + i;
    ul.appendChild(li);
}

上面操作看起来很正常,但实际要很多的插入操作和改动;而每一次的插入都会引起重新渲染,该操作会引发多次渲染,在性能优化方面,有一点是减少DOM操作,因为DOM操作导致了页面的重绘或重排。

  • createDocumentFragment()方法和createElement()方法区别

如果是用createDocumentFragment()方法操作

var ul = document.getElementById("ul");
var fragment = document.createDocumentFragment();
for (var i = 0; i < 50; i++) {
    var li = document.createElement("li");
    li.innerHTML = "index: " + i;
    fragment.appendChild(li);
}
ul.appendChild(fragment);

相比createElement()方法,这次是先将这些元素添加到fragment中,再统一将fragment添加到页面,会减少页面渲染dom的次数,效率会明显提升。因为fragment文档片段存在于内存中,并不在DOM中,所以将子元素插入到文档片段中时不会引起页面回流(新创建的fragment片段在文档内是没有对应的标签的,这里添加的是片段的所有子节点)

  • createTextNode()方法

该方法会创建一个文本节点。

HTML元素通常是由元素节点和文本节点组成。创建一个标题 (h1), 你必须创建 "h1" 元素和文本节点:

var h = document.createElement("h1")
var t = document.createTextNode("Hello World");
h.appendChild(t);

DOM更改:添加、移除、替换、插入

// 添加、删除子元素
ele.appendChild(el);
ele.removeChild(el);

// 替换子元素
ele.replaceChild(el1, el2);

// 插入子元素
parentElement.insertBefore(newElement, referenceElement);

前面三个用法就一目了然,对于insertBefore()方法来举个例子:

<ul id="ul">
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
var newEle = document.createElement('li');
var textNode = document.createTextNode('insertNode');
newEle.appendChild(textNode);

var ul = document.getElementById('ul');
ul.insertBefore(newEle, ul.firstChild);

页面输出:

insertNode
1
2
3

DOM查询

元素查询的API返回的的结果是DOM节点或者DOM节点的列表

getElementById()  
getElementsByName()  
getElementsByTagName()
getElementsByClassName()
querySelector()
querySelectorAll() 

querySelector() 方法返回匹配指定 CSS 选择器元素的第一个子元素, 该方法只返回匹配指定选择器的第一个元素。如果要返回所有匹配元素,需要使用 querySelectorAll() 方法替代.

document.querySelector("#test"); // 获取到id名为test的首个元素
  • querySelector系列方法与getElementBy系列方法对比
  1. 得到的元素不是需要很麻烦的多次getElementBy..的话,尽量使用getElementBy系列方法,因为getElementBy系列执行速度更快。
  2. 得到的元素需要很麻烦的多次getElementBy...组合才能得到的话使用querySelector,方便。
  3. querySelector()选择的标签是静态的,也就是说在选中之后,能够一直保存,也就是脱离了被选择的成为副本。而getelementsBy系列方法是动态的,相互映射,在调用时,变化可以及时的反映在页面上。
// 用 querySelector 操作元素
var ul = document.querySelector('ul');
var list = ul.querySelectorAll('li');
for (var i = 0; i < 3; i++) { // 创建3个新的li标签,添加到ul列表中
    ul.appendChild(document.createElement('li'));
}
console.log(list.length); // 3  
// 输出的是添加前li的数量3,而非此时li的总数量6
var ul = document.getElementsByTagName('ul')[0];
var list = ul.getElementsByTagName('li');
for (var i = 0; i < 3; i++) { // 创建3个新的li标签,添加到ul列表中
    ul.appendChild(document.createElement('li'));
}
console.log(list.length); // 6
  • 还有元素的DOM导航方法:
// 获取父元素、父节点
var parent = ele.parentElement;
var parent = ele.parentNode;

// 获取子节点,子节点可以是任何一种节点,可以通过nodeType来判断
var nodes = ele.children;    

// 查询子元素
var els = ele.getElementsByTagName('li');
var els = ele.getElementsByClassName('test');

// 当前元素的第一个/最后一个子元素节点
var el = ele.firstElementChild;
var el = ele.lastElementChild;

// 下一个/上一个兄弟元素节点
var el = ele.nextElementSibling;
var el = ele.previousElementSibling;

属性操作

getAttribute(key)
setAttribute(key,value)
hasAttribute(key)
removeAttribute(key)  
点赞
收藏
评论区
推荐文章
马丁路德 马丁路德
4年前
对 JavaScript 中事件循环的理解​
一、是什么JavaScript在设计之初便是单线程,即指程序运行时,只有一个线程存在,同一时间只能做一件事为什么要这么设计,跟JavaScript的应用场景有关JavaScript初期作为一门浏览器脚本语言,通常用于操作DOM,如果是多线程,一个线程进行了删除DOM,另一个添加DOM,此时浏览器该如何处理?为了解决单
凯特林 凯特林
4年前
Vue 项目性能优化—实践指南
Vue项目性能优化—实践指南前言Vue框架通过数据双向绑定和虚拟DOM技术,帮我们处理了前端开发中最脏最累的DOM操作部分,我们不再需要去考虑如何操作DOM以及如何最高效地操作DOM;但Vue项目中仍然存在项目首屏优化、Webpack编译配置优化等问题,所以我们仍然需要去关注Vue项目性能方面的优化,使项目具有更高效
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Karen110 Karen110
4年前
一篇文章带你了解JavaScript htmldom 元素
这篇文章将教会大家如何查找和访问网页中的HTML元素。一、找到HTML元素通常,使用JavaScript,想操作HTML元素。要做到这一点,必须先找到元素。有几种方法可以做到这一点。找到DOM中的HTML元素的最简单的方法,是利用元素的id。使用id"intro"找到元素:varmyElementdocument.getElementById("in
Souleigh ✨ Souleigh ✨
4年前
Vue 性能优化
前言Vue框架通过数据双向绑定和虚拟DOM技术,帮我们处理了前端开发中最脏最累的DOM操作部分,我们不再需要去考虑如何操作DOM以及如何最高效地操作DOM;但Vue项目中仍然存在项目首屏优化、Webpack编译配置优化等问题,所以我们仍然需要去关注Vue项目性能方面的优化,使项目具有更高效的性能、更好的用户体验。本文是作者通过实际
Jacquelyn38 Jacquelyn38
4年前
面试官:JavaScript的数据类型你了解多少?
前言作为JavaScript的入门知识点,Js数据类型在整个JavaScript的学习过程中其实尤为重要。最常见的是边界数据类型条件判断问题。我们将通过这几个方面来了解数据类型:概念检测方法转换方法概念undefined、Null、Boolean、String、Number、Symbol、BigInt为基础类型;Ob
Chase620 Chase620
4年前
面试官问 Vue 性能优化,我该怎么回答
前言Vue框架通过数据双向绑定和虚拟DOM技术,帮我们处理了前端开发中最脏最累的DOM操作部分,我们不再需要去考虑如何操作DOM以及如何最高效地操作DOM;但Vue项目中仍然存在项目首屏优化、Webpack编译配置优化等问题,所以我们仍然需要去关注Vue项目性能方面的优化,使项目具有更高效的性能、更好的用户体验。本文是作者通过
Stella981 Stella981
3年前
JavaScript原型深入浅出
不学会怎么处理对象,你在JavaScript道路就就走不了多远。它们几乎是JavaScript编程语言每个方面的基础。事实上,学习如何创建对象可能是你刚开始学习的第一件事。对象是键/值对。创建对象的最常用方法是使用花括号{},并使用点表示法向对象添加属性和方法。letanimal{}animal.name
Stella981 Stella981
3年前
Jquery元素追加和删除
介绍  DOM是DocumentObjectModeule的缩写,一般来说,DOM操作分成3个方面。1、DOMCore   DOMCore并不专属于javascript,任何一种支持DOM的程序设计语言都可以使用它,用途也远不止仅限于网页,也可以用来处理任何一种使用标记语言编写出来的文档,如XML。   例如:
Stella981 Stella981
3年前
Javascript操作DOM常用API总结
        文本整理了javascript操作DOM的一些常用的api,根据其作用整理成为创建,修改,查询等多种类型的api,主要用于复习基础知识,加深对原生js的认识。基本概念        在讲解操作DOM的api之前,首先我们来复习一下一些基本概念,这些概念是掌握api的关键,必须理解它们。Node类型
Wesley13 Wesley13
3年前
JQ动态生成节点绑定事件无效问题
最近做项目的时候遇见了一个问题,通过jq将动态节点绑定到dom节点上,并且为动态节点绑定方法,此方法再次为动态节点添加动态节点,但在刷新之后,动态节点上的方法失效了,过程为:创建动态节点动态节点绑定方法添加动态节点刷新后点击动态节点方法失效。<!DOCTYPEhtml<html<head</head<body
码界流光
码界流光
Lv1
一别家山音信杳,百种相思,肠断何时了。
文章
5
粉丝
0
获赞
0