创建元素
在DOM的操作中,可以使用createElement
方法来创建任何你想要创建的HTML元素。
例如下方代码,创建一个 p 元素:
- document.createElement('p');
上面这行代码将会创建一个 p 元素。需要注意的是,这个时候只是创建了一个 p 元素,但在 HTML 中并看不到你所添加的 p 元素。
因为这个时候你只是创建了 p 元素,并没有放到你需要放置的地方!为了使用元素成为DOM的一部分,需要做以下两件事:
- 找到一个作为父元素的元素
- 使用
appendChild
方法,将元素添加到指定的元素中
例如下方这个示例:
- <body>
- <h1>H1元素</h1>
- <script>
- let newElement = document.createElement('p');
- newElement.textContent = '新创建的p元素';
- document.body.appendChild(newElement);
- </script>
- </body>
上面的代码中,通过 document.body
访问的到父元素是 body
元素。也就是说,在 body
元素上调用 appendChild()
方法,并在这个方法中传递一个参数,这个参数就是我们新创建的元素,也就是示例中的 newElement
。
在执行 document.body.appendChild(newElement)
之间,虽然使用 document.createElement('p')
创建了 p
元素,但在 HTML 中并看不到。所以说,要在 HTML 文档中想要看到 document.createElemet()
方法创建的 HTML 元素,还需要使用类似 appendChild()
这样的方法。
需要注意的是,使用appendChild()
函数将新创建的元素添加到指定的父元素下,都将成为该父元素的最后一个子元素,也就是lastChild
。
比如说上面的示例,body
元素已经有了h1
和script
元素。新创建的p
将作为body
的最后一个子元素,被追加到script
之后,也就是</body>
标签之前。
将新创建的HTML元素插入到DOM中,appendChild
仅是一种方式,其实我们还有别的方式。
比如,想在h1
标签之后插入新创建的元素newElement
(事实是就是新创建的p
元素),那么可以通过在指定的父节点上调用insertBefore()
函数来实现。
insertBefore()
函数接受两个参数。第一个参数是要插入的元素(比如newElement
),第二个参数是你想插入元素的位置,比如h1
元素之后(但在script
元素之前)。
如下方示例:
- <body>
- <h1>h1元素</h1>
- <script>
- var newElement = document.createElement("p");
- newElement.textContent = "创建的p元素";
- var scriptElement = document.querySelector("script");
- document.body.insertBefore(newElement, scriptElement);
- </script>
- </body>
如图:
或许你会说,既然有insertBefore()
方法,应该也会有一个insertAfter()
方法。事实并非如此。
在 DOM 操作中并没有一个内置的方法在DOM元素之后插入你想要插入的元素。
在DOM的操作当中,如果你想在一个元素之后插入你想要插入的元素,可以借助insertBefore()
函数来实现,比如在上面的示例中,把新创建的元素添加到h1
和script
之间,当然,使用insertBefore(newElement, scriptElement)
很容易实现,但我们还可以借助其他的方式,来个曲线救国。
如下代码:
- <body>
- <h1>h1元素</h1>
- <script>
- var newElement = document.createElement("p");
- newElement.textContent = "创建的p元素";
- var scriptElement = document.querySelector("script");
- var h1Element = document.querySelector("h1");
- document.body.insertBefore(newElement, h1Element.nextSibling);
- </script>
- </body>
如图:
就上面的示例而言,h1Element.nextSibling
调用到的是script
元素。
将newElement
新创建的元素插入到script
元素之前,事实上也实现了在h1
元素之后插入新创建的元素newElement
。
如果目标没有兄弟元素呢?这个例子中的insertBefore
函数非常聪明,它会自动将你想要的元素追加到末尾。
在JavaScript中操作DOM元素,并没有insertAfter
函数,那么咱们可以自己定义一个函数,来达到类似的一个功能。
比如下面这个自定义的insertAfter
函数:
- function insertAfter(target, newElement) {
- target.parentNode.insertBefore(newElement, target.nextSibling)
- }
删除元素
前面我们了解了createElement
方法创建元素。接下来,看看怎么从DOM中删除一个已有元素。
在DOM中,可以使用removeChild
来删除已有的DOM元素。
如下代码:
- <body>
- <h1>h1元素</h1>
- <script>
- var newElement = document.createElement("p");
- newElement.textContent = "创建的p元素";
- document.body.appendChild(newElement);
- document.body.removeChild(newElement);
- </script>
- </body>
通过appendChild
方法将新创建的p
元素newElement
添加到body
元素中,之后删除该元素。
需要注意的是,如果希望从子节点的父节点中调用removeChild
来删除你想要删除的元素,此方法不会遍历DOM。假设没有直接访问元素的父元素,并且不想浪费时间来查找它。那可以通过parentNode
属性,也可以很轻易的删除该元素。比如下面这个示例:
- <body>
- <h1>h1元素</h1>
- <script>
- var newElement = document.createElement("p");
- newElement.textContent = "创建的p元素";
- document.body.appendChild(newElement);
- document.body.removeChild(newElement);
- newElement.parentNode.removeChild(newElement);
- </script>
- </body>
上面的意思是,创建了新元素后,根据这个元素父元素parentNode
移除该元素。
克隆元素
除了在DOM中添加一个新元素和删除一个已有的元素。事实上,还可以克隆一个元素。
在DOM中克隆一个元素方式也很简单,在希望克隆的元素上调用cloneNode
函数,并提供一个true
或false
的参数,以指定是否想克隆元素或元素及其所有子元素。
比如下面这个简单的示例:
- <!DOCTYPE HTML><html>
- <body>
- <div id="outerContainer">
- <div>
- <h1>h1元素</h1>
- </div>
- </div>
- <div id="footer">
- <div class="share">
- <p>p元素</p>
- <img alt="#" src="some.png"/>
- </div>
- </div>
- <script>
- var share = document.querySelector(".share");
- var shareClone = share.cloneNode(false);
- document.querySelector("#footer").appendChild(shareClone);
- </script>
- </body>
- </html>
上面的代码把类名share
的div
赋值给一个share
的变量。接着使用cloneNode
函数克隆这个div
:
- var shareClone = share.cloneNode(false);
上面的代码把新克隆的内容赋值给shareClone
。注意,这里传给cloneNode
的值是false
。这意味着只克隆了类名为share
的div
。
调用cloneNode
后的操作步骤与使用createElement
的步骤相同。
在下一行代码中,把新克隆的元素添加到div#footer
中。
执行上面的代码之后,DOM树就变成下图这样:
接下来修改一下上面的代码,把其中的false
修改为true
:
- var shareClone = share.cloneNode(true);
前面结果不同之处是,这里克隆的不仅是div.share
这个元素,还克隆了该元素的所有后代元素。这个时候的DOM结构如下:
替换元素
在DOM操作中,还可以使用replaceChild()
方法用一个新的DOM节点来替换当前节点。
replaceChild
同样的接收两个参数,第一个参数是新节点,第二个参数就是旧节点(也就是需要被替代的元素节点)。
比如前面的示例,用新创建的newElement
(使用createElement
创建的一个新p
元素)来替代已有的oldElement
(即,DOM中div
为share
的)。
- <!DOCTYPE HTML><html>
- <body>
- <div id="outerContainer">
- <div>
- <h1>h1元素</h1>
- </div>
- </div>
- <div id="footer">
- <div class="share">
- <p>p元素</p>
- <img alt="#" src="some.png"/>
- </div>
- </div>
- <script>
- var newElement = document.createElement('p');
- newElement.textContent = '新创建的p元素';
- var oldElement = document.querySelector('.share');
- oldElement.parentNode.replaceChild(newElement, oldElement)
- </script>
- </body>
- </html>
如图:
如上图圆圈部分将被新的p元素替换掉。
完!