特别声明:如果您喜欢小站的内容,可以点击年卡¥199.00元(
原价: ¥598元)、季卡¥78.00元(原价: ¥168元)、月卡¥28.00元(原价: ¥68元)进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!(^_^)
通过上一节的学习,对JavaScript中的DOM有了一定的认识。虽然对DOM中相关的知识点有一定的概念,但还是缺乏对DOM的实际操作。如果你仔细阅读过上一篇文章的话,你应该会发现,当时也提到了一些DOM操作相关的东西,比如,DOM的增、删、改和查等。那么今天我们就来看看这些方面的东西。
DOM的增
先来看DOM操作中的增。其主要分为两个部分:新创建节点和插入节点。
新创建节点
常用的DOM节点创建有关的API接口主要有:
document.createElement
:创建指定的HTML元素或一个HTMLUnknownElement
document.createTextNode
:创建文本节点document.createDocumentFrame
:创建文档片段document.createAttribute
:创建节点属性document.adoptNode
:从外部文档中获取一个节点document.importNode
:拷贝外部文档的一个节点node.cloneNode
:克隆节点
document.createElement
document.createElement(tagName[, options])
是其中最常用的DOM API之一,主要用来创建由标签名称(tagName
)指定的HTML元素,如果标签名称不是一个有效的HTML元素,将会创建一个HTMLUnknownElement
对象。来看一个简单的示例:
let newEle = document.createElement('div');
let newContent = document.createTextNode('我是一个新创建的div元素')
newEle.appendChild(newContent)
document.body.appendChild(newEle)
注意,通过document.createElement
创建的元素并不属于document
对象,它只是创建出来,并未添加到HTML文档中,需要调用appendChild()
或insertBefore()
等方法将其添加到HTML文档中。
如果你对
HTMLUnknownElement
从未接触,建议你有空花点时间阅读@张鑫旭老湿的《》和@米粽大大翻译的《Custom Elements》。
document.createTextNode
document.createTextNode(text)
创建一个文本节点,参数text
为文本节点的内容。比如:
let newContent = document.createTextNode('我是一个新创建的div元素')
newEle.appendChild(newContent)
创建了一个文本节点newContent
,然后把这个新创建的文本节点通过appendChild()
方法,将其插入到newEle
元素中,当作其内容。document.createTextNode(text)
方法返回的节点,被浏览器当作文本渲染,而不是当作HTML代码渲染,因此会对HTML代码进行转义,可以用来展示用户的输入,避免XSS
攻击。
function escapeUserInput(str) {
var div = document.createElement('div');
div.appendChild(document.createTextNode(str));
return div.innerHTML;
}
var userInput = '<p>危险内容</p>';
var template = '<div>' + escapeUserInput(userInput) + '</div>'
// 此时被转义,危险内容不再危险
<div><p>危险内容</p></div>
但是,该方法不对单引号和双引号转义,因此用来为属性赋值的时候,仍然会被 XSS
攻击:
var userInput = '" onmouseover="console.log(\'危险操作\')" "';
var template = '<div color="' + escapeUserInput(userInput) + '">user set color</div>'
// 被注入一个 onmouseover 操作
<div color="" onmouseover="console.log('危险操作')" "">user set color</div>
其中XSS
攻击属于Web安全方面的知识了,不属于这篇文章的范畴。如果你对XSS
相关的东西感兴趣的话,可以看看下面几篇文章:
document.createDocumentFragment
document.createDocumentFragment()
方法创建一个新空白的DocumentFragment
对象。
DocumentFragments
是DOM节点。它们不是主DOM树的一部分。通常的用例是创建文档片段,将元素附加到文档片段,然后将文档片段附加到DOM树。在DOM树中,文档片段被其所有的子元素代替。
因为文档片段存在于内存中,并不在DOM树中,所以将子元素插入到文档片段时不会引起页面回流(reflow
)(对元素位置和几何上的计算)。因此,使用文档片段document fragments 通常会起到优化性能的作用。
比如下面这个示例,给一个ul
添加10000
个li
,先用拼接字符串的方式来实现:
let start = Date.now()
let str = ''
let newUlEle = document.createElement('ul')
document.body.appendChild(newUlEle)
for (let i = 0; i < 10000; i++) {
str += '<li>第' + i + '个子节点</li>'
}
newUlEle.innerHTML = str
console.log('耗时' + (Date.now() - start) + 'ms');
多次刷新,可以看到创建10000
个li
时,渲染所需要的时间如下图:
把上面的示例,换成append()
的方式,逐个添加对应的li
:
let start = Date.now()
let str = ''
let newUlEle = document.createElement('ul')
document.body.appendChild(newUlEle)
for (let i = 0; i < 10000; i++) {
let liEle = document.createElement('li')
liEle.textContent = '第' + i + '个子节点'
newUlEle.appendChild(liEle)
}
console.log('耗时:' + (Date.now() - start) + 'ms')
这种方法所费时间如下图:
都说第二种方法要比第一种方法耗时,看上去有点像。接下来再来看createDocumentFragment
的方法。可以预见的是,这种方法肯定比第二种强,但应该没有第一种快:
let start = Date.now()
let str = ''
let newUlEle = document.createElement('ul')
document.body.appendChild(newUlEle)
let fragment = document.createDocumentFragment()
for (let i = 0; i < 10000; i++) {
let liEle = document.createElem
如需转载,烦请注明出处:https://www.w3cplus.com/javascript/operate-dom.html
如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!