JavaScript学习笔记:DOM的操作

编辑推荐:3月31日前,点击注册激活 Coding.net 立赠30天付费会员 ,体验极速代码托管服务!
通过上一节的学习,对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>&lt;p&gt;危险内容&lt;/p&gt;</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添加10000li,先用拼接字符串的方式来实现: 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'); 多次刷新,可以看到创建10000li时,渲染所需要的时间如下图: 把上面的示例,换成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.createElement('li') liEle.textContent = '第' + i + '个子节点' fragment.appendChild(liEle) } newUlEle.appendChild(fragment) console.log('耗时:' + (Date.now() - start) + 'ms')

document.createAttribute()

document.createAttribute(attrName)方法创建并返回一个新的属性节点。这个方法不是很常用,因为添加属性通常使用node.setAttribute() let node = document.getElementById('content') let attr = document.createAttribute('title') attr.nodeValue = 'Hello JavaScript!' node.setAttributeNode(attr) 上面的代码会给div#content的元素添加一个title属性,而且这个title属性的值为Hello JavaScript! 同样的,document.createAttribute()虽然创建了属性节点,如果不通过setAttributeNode()方法的话,创建的属性的节点是不会运用到对应的元素节点上的。该方法的返回值是一个Attr类型的节点。借助nodeValue给该节点赋值,然后给该属性节点设置对应的属性值。等同的效果,常常使用setAttribute()方法来替代该方法。后续我们会介绍到setAttribute()方法相关的知识。

document.adoptNode

document.adoptNode(externalNode) 从其他的 document 中获取一个节点(externalNode),并将该节点以及它的所有子节点从原文档删除, 并且它的 ownerDocument 属性会变成当前的 document。之后你可以把这个节点插入到当前文档中,不常用,了解即可。 // 该函数用来从本文档的第一个 iframe 中获取第一个 element 元素, // 并插入到当前文档树中 function getEle(){ var iframe = document.getElementsByTagName("iframe")[0], ele = iframe.contentWindow.document.body.firstElementChild; if(ele){ document.body.appendChild(document.adoptNode(ele)) }else{ alert("没有更多元素了") } } document.getElementById("move").onclick = getEle 注意,该方法在同一 document 下的不同两个元素中也可以使用,可以实现从左边栏列表中选取某些元素加载到右边栏的功能。如果节点资源来自不同的源的时候,调用 adoptNode 可能会失败。 有些情况下,将外部文档的节点插入当前文档之前,你需要使用 document.importNode() 从外部文档导入源节点,了解更多细节

document.importNode

document.importNode(externalNode, deep) 这个接口也不常用,作用是拷贝外部文档的一个节点(externalNode)。deep 表明是否要导入节点的后代节点,默认为 false 不导入后代节点。 var iframe = document.getElementsByTagName("iframe")[0]; var oldNode = iframe.contentDocument.getElementById("myNode"); var newNode = document.importNode(oldNode, true); document.getElementById("container").appendChild(newNode); 注意,这个方法仅拷贝节点,此时,节点存在于内存中,还需要插入当前文档中才能显示。

node.cloneNode

node.cloneNode(deep)方法返回该节点的一个副本,deep可选,表明是否采用深度克隆,如果为true,则该节点的所有后代节点也都会被克隆,否则,只克隆该节点本身。 let node = document.getElementById('content') let cloneNode = node.cloneNode(true) cloneNode.id = "newId" document.body.appendChild(cloneNode) 上面的这个小示例,克隆了div#content以及其所有后代节点,并且把新克隆的元素的id赋值为newId,然后再把新克隆出来的所有节点重新插入body中。最终的效果如下: 上面的示例,演示了,使用node.cloneNode(true)可以克隆节点的所有后代节点以及其所有属性。那么对于绑定的事件是否也能被克隆呢?还是通过示例来验证一下,看看事件是否也会被克隆。 <div id="box"> <button id="clone" onclick="console.log('Click Clone Button')">Clone Me!</button> </div> <div id="new"></div> // cloneNode let btn = document.getElementById('clone') let box = document.getElementById('box') let newDiv = document.getElementById('new') newDiv.appendChild(box.cloneNode(true)) 上面的示例使用了内联方式直接把事件写在HTML标签上。从结果我们可以看到绑定在HTML标签上的事件也被克隆了。 接下来在上例的基础上做一下调整,把内联方式换成绑定在节点对象上的事件: let btn = document.getElementById('clone') let box = document.getElementById('box') let newDiv = document.getElementById('new') btn.onclick = function () { console.log('click clone') } newDiv.appendChild(box.cloneNode(true)) 从结果可以看出,绑定在节点对象的事件在克隆的副本并不包含事件处理程序。接着再做一下调整,使用addEventListener()方法把事件添加在节点上: btn.addEventListener('click', function (){ console.log('Click clone!') }) 得到的效果其实和上图是一样的。也就是说,克隆的时候,addEventListener()绑定的事件并没有被克隆。
从上面的示例可以证明,副本节点只能绑定使用内联方式绑定的事件处理函数。简单点说,只有内联在HTML元素的事件,才会被cloneNode()克隆
注意,这个拷贝的节点并不在文档中,需要自行添加到文档中。同时拷贝的节点有可能会导致节点的的 id 属性重复,最好修改新节点的 id,而 name 属性也可能重复,自行决定是否需要修改。

节点修改

DOM节点修改有关的API有:
  • node.appendChild():插入一个新节点
  • node.insertBefore():插入一个新节点
  • node.removeChild():删除一个节点
  • node.replaceChild():替换一个节点
其中node.appendChildnode.insertBefore属于DOM中的新节点插入,而removeChild属于DOM中的replaceChild属于DOM中的。这一节,咱们只先聊增这一部分,对于删和改,我们后面会单独介绍。

node.appendChild

parentNode.appendChild(child)方法将一个节点child添加到指定的父节点parentNode的子节点列表的末尾。本方法返回值为要插入的这个节点。 let pEle = document.createElement('p') pEle.textContent = '我是新添加的p元素' document.body.appendChild(pEle) 上面的示例创建了一个新的段落元素pEle,然后使用appendChild()将这个新创建的元素添加到body的最末尾。 使用appendChild()方法的时候有一点需要注意。如果被插入的节点已经存在文档树中,则节点会被从原先的位置移除,并插入到新的位置。当然,被移动的元素被绑定的事件也会被同步过去,比如: <div id="old"> <p id="move">我是一个段落元素</p> </div> <div id="new"></div> <button id="btn">创建元素</button> let pEle = document.getElementById('move') let newEle = document.getElementById('new') let btnEle = document.getElementById('btn') pEle.addEventListener('click', function() { console.log('click me!') }) btnEle.addEventListener('click', function () { pEle.textContent = '我是新添加的p元素' newEle.appendChild(pEle) }) 如果要保留原来的这个子节点的位置,则可以用 Node.cloneNode 方法复制出一个节点的副本,然后再插入到新位置。这个方法只能将某个子节点插入到同一个文档的其他位置,如果你想跨文档插入,需要先调用document.importNode方法。还有,如果appendChild()方法的参数是DocumentFragment节点,那么插入的是DocumentFragment的所有子节点,而不是DocumentFragment节点本身。此时,返回值是一个空的DocumentFragment节点。

node.insertBefore

parentNode.insertBefore(child, referenceNode)方法将一个节点child插入作为父节点parentNode的一个子节点,并且位置在参考节点referenceNode之前。 如果第二个参数referenceNodenull,则插入位置你父节点的末尾: parentNode.insertBefore(node, null); // 等价于 parentNode.appendChild(node);
注意,第二个参数为null时不能省略,否则会报错。
来看一个小示例: <div id="parent"> 我是父节点 <p id="child">我是旧的子节点</p> </div> <button id="btn">插入节点</button> let parentEle = document.getElementById('parent') let childEle = document.getElementById('child') let btnEle = document.getElementById('btn') btnEle.addEventListener('click', function () { let newEle = document.createElement('span') newEle.textContent = '我是新添加节点的文本内容' parentEle.insertBefore(newEle, childEle) }) 使用这个方法可以模拟prependChild,产生类似于appendChild(),但是将节点插入作为指定父节点的第一个子节点: Node.prototype.prependChild = function (node) { return this.insertBefore(node, this.firstChild) } let parentEle = document.getElementById('parent') let btnEle = document.getElementById('btn') btnEle.addEventListener('click', function () { let newEle = document.createElement('p') newEle.textContent = '我是新添加节点的文本内容' parentEle.prependChild(newEle) }) 其实这个效果和前面的效果是类似的。同样的,使用这个方法还可以模拟insertAfter,将节点要插在父节点的某个子节点后面: Node.prototype.insertAfter = function(node, referenceNode) { return this.insertBefore(node, referenceNode.nextSibling); } appendChild 类似,如果插入的节点是文档中已经存在的节点,则会移动该节点到指定位置,并且保留其绑定的事件。

DOM的删

DOM节点的删除主要API是node.removeChild。可以使用parentNode.removeChild(child)删除指定父节点parentNode的一个子节点child,并返回被删除的节点。 这个方法是要在被删除的节点的父节点上调用的,而不是在被删除节点上调用的,如果参数节点不是当前节点的子节点,removeChild 方法将报错: // 通过 parentNode 属性直接删除自身 var node = document.getElementById('deleteDiv'); if (node.parentNode) { node.parentNode.removeChild(node); } // 也可以封装以下作为一个方法直接使用: Node.prototype.remove = function(node) { if (node.parentNode) { return node.parentNode.removeChild(node); } throw new Error('Can not delete.'); } node.remove(); 使用这个方法也可以很简单的模拟 removeAllChild Node.prototype.removeAllChild = function() { var deleteNode = [] while (this.firstChild) { deleteNode.push(this.removeChild(this.firstChild)); } return deleteNode; } 被移除的这个子节点仍然存在于内存中,只是不在当前文档的 DOM 中,仍然还可以被添加回文档中。但是如果不使用一个变量保存这个节点的引用,被删除的节点将不可达,会在某次垃圾回收被清除。

DOM的改

parentNode.replaceChild(newChild, oldChild) 方法用指定的节点newChild替换当前节点parentNode的一个子节点oldChild,并返回被替换的节点oldChild <div id="parent"> <p id="child">我是旧的第一个子节点</p> </div> <button id="btn">替换节点</button> let parentEle = document.getElementById('parent') let oldEle = document.getElementById('child') let btnEle = document.getElementById('btn') btnEle.addEventListener('click', function () { let newEle = document.createElement('p') newEle.setAttribute('id', 'newChild') newEle.textContent = '我是新添加节点的文本内容' parentEle.replaceChild(newEle, oldEle) })

简单的总结一下

DOM中的节点操作对应的主要API有:
  • appendChild():用于向childNodes列表的末尾添加一个节点。返回新增的节点。
  • insertBefore():接收两个参数:要插入的节点和作为参照的节点。插入节点后,被插入的节点会变成参照节点的前一个同胞节点。同时被方法返回。
  • replaceChild():接收两个参数:要插入的节点和要替换的节点。要替换的节点将由这个方法返回并从文档树中移除。同时由要插入的节点占据其位置。
  • removeChild():接收一个参数,即要移除的节点。返回被移除的节点。
这四个方法都是操作的某个节点的子节点,也就是说,要使用这几个方法必须先取得父节点。另外并不是所有节点都有子节点,如果在不支持子节点的节点上,调用了这些方法,将会导致错误。

DOM的查

DOM节点中的查主要包括:查找元素(类似于CSS中的选择器)和节点查找。

查找元素

先来看DOM中怎么查找到元素,也就是说选择到你想要的元素。在DOM中查找元素(选择到想要的元素)对应的API主要有:
  • document.getElementById(id):匹配特定id的元素
  • document.getElementsByName(name):根据给定的name 返回一个在 (X)HTML documentNodeList集合
  • document.getElementsByTagName(tagName):返回一个包括所有给定标签名称的元素的HTML集合HTMLCollection
  • document.getElementsByClassName(className):返回包含了所有指定类名的子元素的类数组对象
  • document.querySelector(selector):返回文档中与指定选择器或选择器组匹配的第一个Element
  • document.querySelectorAll(selector):返回与指定的选择器组匹配的文档中的元素列表。返回的对象是NodeList
假设我们有一个简单的DOM文档: <div id="box"> <h3>Title</h3> <ul class="list"> <li class="item">Item1</li> <li class="item">Item2</li> <li class="item">Item3</li> <li class="item">Item4</li> <li class="item">Item5</li> </ul> <p id="intro">Intro ...</p> </div> 为了更好的说明前面的几个API,后续中的示例,都会采用这个DOM结构。其对应的DOM树不再绘制了。

document.getElementById(id)

document.getElementById(id)返回的是一个Element对象,用来匹配文档中指定的id元素。如果没有找到对应的元素,该方法会返回null。另外,document.getElementById()方法不会搜索不在文档中的元素。当创建一个元素,并且分配id后,必须要使用insertBefore或其他类似的方法把元素插入到文档之后才能使用document.getElementById()获取到。 来看一个示例: let idEle = document.getElementById('intro') let btnEle = document.getElementById('btn') btnEle.addEventListener('click', function () { console.log(`能匹配到的: ${idEle}`) console.log(idEle) let newEle = document.createElement('section') newEle.id = 'main' newEle.textContent = '我是新添加的元素' console.log(`未插入到DOM的新元素newEle: ${document.getElementById('main')}`) console.log(document.getElementById('main')) let box = document.getElementById('box') box.insertBefore(newEle, idEle) console.log(`插入到DOM的新元素newEle: ${document.getElementById('main')}`) console.log(document.getElementById('main')) }) 来看输出的结果: 比如上面示例,通过document.getElementById()之后,咱们获取了DOM上的节点,这个时候可以对该节点做很多事情,比如查询内容和属性,或者其他任何操作,甚至可以删除它,克隆它,或者将它移动到DOM树的其它节点上。 注意,document.getElementById(id)中的id参数是有大小写敏感的,所以document.getElementById('Intro')无法获取到元素<p id="intro">Intro ...</p>。另外还有就是,如果文档中有多个相同的id(这种情形一般不存在)时,只会返回第一个。

document.getElementsByName(name)

document.getElementsByName(name)将根据给定的name返回一个在document的节点列表集合。name属性只有在HTML文档中可用。该方法返回的是一个NodeList集合,这个集合包含name属性为指定值的所有元素,比如<meta><object>,甚至那些不支持name属性但是添加了name自定义属性的元素也包含其中。 该方法常用于取得单选按钮。同样也会返回HTMLCollection对象。HTMLCollection对象可以通过length属性访问元素长度,通过[]方括号语法访问对象中的项。方括号中既可以是数字,也可以是字符串索引值。

document.getElementsByTagName(tagName)

document.getElementsByTagName(tagName)将会返回一个包括所有给定标签名称tagName的元素的HTML集合HTMLCollection。整个文件结构都会被搜索,包括根节点。返回的HTML集合是动态的,意味着它可以自动更新来保持和DOM树同步,而不用再次调用document.getElementsByTagName(tagName) let liEle = document.getElementsByTagName('li') let btnEle = document.getElementById('btn') btnEle.addEventListener('click', function () { console.log(`能匹配到的: ${liEle}`) console.log(liEle.length) Object.keys(liEle).forEach(key => { console.log(key, liEle[key]) }) }) 比如上面的示例,通过getElementsByTagName('li')获取了文档中所有的<li>元素。其开始于一个具体的父元素并且从它自上而下递归地在DOM树中搜索符合标签名称参数的子元素。刚才也说了,其返回的是一个动态的HTMLCollection对象。获得这个对象之后,可以对其做一些遍历操作。比如上面使用Object.keys()遍历出li
有关于JavaScript中对象遍历相关的操作可以阅读《如何遍历JavaScript中对象属性》和《对象属性的枚举》。
有一点需要注意,调用 getElementsByTagName() 的不是那个文件节点 document,事实上是使用这个方法 element.getElementsByTagName()

document.getElementsByClassName(className)

document.getElementsByClassName(className)返回一个包含了所有指定类名的子元素的类数组对象。当在document对象上调用时,会搜索整个DOM文档,包含根节点。你也可以在任意元素上调用getElementsByClassName()方法,它将返回的是以当前元素为根节点,所有指定类名的子元素。 比如,获取所有classitem的元素: document.getElementsByClassName('item') 如果你想获取多个class的元素时,可以用空格来隔开,比如说,同时获取所有class同时包括btnbtn-lg的元素: document.getElementsByClassName('btn btn-lg') 如果你想获取某个元素的子节点中对应class的元素时,你也可以像下面这样操作: document.getElementById('box').getElementsByClassName('item')

document.querySelector(selector)

document.querySelector(selector)方法可以帮助你选择一个HTML元素。如果选择了多个HTML元素,其总是返回第一个元素。它看起来像这样: document.querySelector('li') 使用这个方法可以通过idclass以及标签元素,甚至是元素的一些属性可以选择一个元素。
  • 使用一个id选择元素,需要在id前使用#
  • 使用一个class选择元素,需要在class前使用.
  • 使用一个标签选择元素,可以直接把元素标签当作选择器
甚至为了更好的理解或者记忆,只要满足CSS的选择器,那么都可以被运用于document.querySelector(selector)中的selector选择器。

document.querySelectorAll(selector)

document.querySelectorAll(selector)可以帮助你选择多个元素。这个方法中的selectordocument.querySelector()具有相同的语法。唯一不同的是,你可以通过用逗号,分隔来选择多个元素。 比如: var matches = document.querySelectorAll("div.note, div.alert");

节点查找

DOM中节点共有12种类型,每种类型分别表示文档中不同的信息标记。每个节点都拥有各自的特点、数据和方法,也与其他节点存在某种关系。节点之间的关系构成了层次,而所有页面标记则表现为一个以特定节点为根节点的树形结构。用张图来描述: 所有的节点都有这些属性,都是可以用于访问相关的node节点:
  • Node.childNodes: 访问一个单元素下所有的直接子节点元素,可以是一个可循环的类数组对象。该节点集合可以保护不同的类型的子节点(比如text节点或其他元素节点)。
  • Node.firstChild: 与childNodes数组的第一个项(Element.childNodes[0])是同样的效果,仅仅是快捷方式。
  • Node.lastChild: 与childNodes数组的最后一个项(Element.childNodes[Element.childNodes.length-1])是同样的效果,仅仅是快捷方式。
  • Node.parentNode: 访问当前节点的父节点,父节点只能有一个,祖节点可以用Node.parentNode.parentNode的形式来访问。
  • Node.nextSibling: 访问DOM树上与当前节点同级别的下一个节点。
  • Node.previousSibling: 访问DOM树上与当前节点同级别的上一个节点。
用张图来阐述,会更清晰: 通过这张图,理解起来就简单多了,但有个非常重要的知识点:那就是元素之间不能有空格,如果ulli之间有空格的话,就会被认为是内容为空的text node节点,这样ul.childNodes[0]就不是第一个li元素了。相应地,<p>的下一个节点也不是<ul>,因为<p><ul>之间有一个空行的节点,一般遇到这种情况需要遍历所有的子节点然后判断nodeType类型。 根据上面的描述,我们可以把DOM中的节点相互之间存在着的各种关系分为:父子关系,兄弟关系等:

父关系相关的API

  • parentNode:每个节点都有一个parentNode属性,它表示元素的父节点。Element的父节点可能是ElementDocumentDocumentFragment;如果不存在,则返回null
  • parentElement:返回元素的父元素节点,与parentNode的区别在于,其父节点必须是一个Element元素,如果不是,则返回null

子关系API

  • children:返回一个实时的HTMLCollection,子节点都是Element;保存的是该节点的第一层元素子节点
  • childNodes:返回一个实时的NodeList,表示元素的子节点列表,注意子节点可能包含文本节点、注释节点等;
  • firstChild:返回第一个子节点,不存在返回null,与之相对应的还有一个firstElementChild
  • lastChild:返回最后一个子节点,不存在返回null,与之相对应的还有一个lastElementChild

兄弟关系型API

  • previousSibling:节点的前一个节点,如果不存在则返回null。注意有可能拿到的节点是文本节点或注释节点,与预期的不符,要进行处理一下。
  • nextSibling:节点的后一个节点,如果不存在则返回null。注意有可能拿到的节点是文本节点,与预期的不符,要进行处理一下。
  • previousElementSibling:返回前一个元素节点,前一个节点必须是Element
  • nextElementSibling:返回后一个元素节点,后一个节点必须是Element

总结

DOM操作在JavaScript还是很重要的,简单点说,所有的交互操作都是基于DOM来操作的。而DOM中的操作,最为熟悉的就是对DOM的增、删、改、查。今天的内容也就围绕着这几个方面展开。因为涉及到的内容较多,可能会有遗漏或者说零乱。如果你觉得上面不对之处,还请路过大神指正。

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等伟德19463331脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。
如需转载,烦请注明出处:https://www.w3cplus.com/javascript/operate-dom.html
返回顶部