创建节点

假设我们要编写一个脚本,将文档中的所有图像(<img>标签)替换为其alt属性中的文本,该文本指定了图像的文字替代表示。

这不仅涉及删除图像,还涉及添加新的文本节点,并替换原有图像节点。为此我们使用document.createTextNode方法。

  1. <p>The <img src="img/cat.png" alt="Cat"> in the
  2. <img src="img/hat.png" alt="Hat">.</p>
  3. <p><button onclick="replaceImages()">Replace</button></p>
  4. <script>
  5. function replaceImages() {
  6. let images = document.body.getElementsByTagName("img");
  7. for (let i = images.length - 1; i >= 0; i--) {
  8. let image = images[i];
  9. if (image.alt) {
  10. let text = document.createTextNode(image.alt);
  11. image.parentNode.replaceChild(text, image);
  12. }
  13. }
  14. }
  15. </script>

给定一个字符串,createTextNode为我们提供了一个文本节点,我们可以将它插入到文档中,来使其显示在屏幕上。

该循环从列表末尾开始遍历图像。我们必须这样反向遍历列表,因为getElementsByTagName之类的方法返回的节点列表是动态变化的。该列表会随着文档改变还改变。若我们从列表头开始遍历,移除掉第一个图像会导致列表丢失其第一个元素,第二次循环时,因为集合的长度此时为 1,而i也为 1,所以循环会停止。

如果你想要获得一个固定的节点集合,可以使用数组的Array.from方法将其转换成实际数组。

  1. let arrayish = {0: "one", 1: "two", length: 2};
  2. let array = Array.from(arrayish);
  3. console.log(array.map(s => s.toUpperCase()));
  4. // → ["ONE", "TWO"]

你可以使用document.createElement方法创建一个元素节点。该方法接受一个标签名,返回一个新的空节点,节点类型由标签名指定。

下面的示例定义了一个elt工具,用于创建一个新的元素节点,并将其剩余参数当作该节点的子节点。接着使用该函数为引用添加来源信息。

  1. <blockquote id="quote">
  2. No book can ever be finished. While working on it we learn
  3. just enough to find it immature the moment we turn away
  4. from it.
  5. </blockquote>
  6. <script>
  7. function elt(type, ...children) {
  8. let node = document.createElement(type);
  9. for (let child of children) {
  10. if (typeof child != "string") node.appendChild(child);
  11. else node.appendChild(document.createTextNode(child));
  12. }
  13. return node;
  14. }
  15. document.getElementById("quote").appendChild(
  16. elt("footer", "—",
  17. elt("strong", "Karl Popper"),
  18. ", preface to the second editon of ",
  19. elt("em", "The Open Society and Its Enemies"),
  20. ", 1950"));
  21. </script>