坚持使用JS DOM Manipulation

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了坚持使用JS DOM Manipulation相关的知识,希望对你有一定的参考价值。

我坚持使用这个简单的JS DOM操作。以下是我的html标记。我试图用JS动态生成单个列表项。

我的问题:每个单独的Span标签应该包含一个对象数组中的单个项目,但在我的情况下,一个span标签包含所有元素。我怎样才能让它发挥作用?我知道这一定非常简单,但我无法弄清楚我在哪里错了?

HTML代码:

<ul class="collection" id="web-book-list">
            <li class="collection-item">
              <span class="flow-text">item 1</span>
              <a href="#!" class="secondary-content"
                ><i class="small material-icons black-text">visibility</i></a
              >
              <a href="#!" class="secondary-content"
                ><i class="small material-icons red-text">delete_forever</i></a
              >
            </li>
            <li class="collection-item">
              <span class="flow-text">item 2</span>
              <a href="#!" class="secondary-content"
                ><i class="small material-icons black-text">visibility</i></a
              >
              <a href="#!" class="secondary-content"
                ><i class="small material-icons red-text">delete_forever</i></a
              >
            </li>
        </ul>

JS代码:

let bookList = document.getElementById("web-book-list");
  // Create element
  let li = document.createElement("li");
  let span = document.createElement("span");
  let linkA = document.createElement("a");
  let linkB = document.createElement("a");
  let visible = document.createElement("i");
  let deleteBtn = document.createElement("i");

  // Add classes to elements
  li.className = "collection-item";
  span.className = "flow-text";
  linkA.className = "secondary-content";
  linkB.className = "secondary-content";
  visible.className = "small material-icons black-text";
  deleteBtn.className = "small material-icons red-text";

  // create text nodes
  visible.appendChild(document.createTextNode("visibility"));
  deleteBtn.appendChild(document.createTextNode("delete_forever"));

  linkA.appendChild(visible);
  linkB.appendChild(deleteBtn);

  //Loop through the webBooks

  for (let i = 0; i < webBooks.length; i++) {
    console.log(webBooks[i]);
    span.innerHTML += webBooks[i].name; // Problem is here!

    li.appendChild(span);
    li.appendChild(linkA);
    li.appendChild(linkB);
    bookList.appendChild(li);
  }
  console.log(bookList);
答案

删除+=并附加使用bookList.appendChild(li.cloneNode(true));

var bookList = document.getElementById("web-book-list");
  // Create element
  var li = document.createElement("li");
  var span = document.createElement("span");
  var linkA = document.createElement("a");
  var linkB = document.createElement("a");
  var visible = document.createElement("i");
  var deleteBtn = document.createElement("i");

  // Add classes to elements
  li.className = "collection-item";
  span.className = "flow-text";
  linkA.className = "secondary-content";
  linkB.className = "secondary-content";
  linkA.href = "#0";
  linkB.href = "#0";
  visible.className = "small material-icons black-text";
  deleteBtn.className = "small material-icons red-text";

  // create text nodes
  visible.appendChild(document.createTextNode("visibility "));
  deleteBtn.appendChild(document.createTextNode("delete_forever"));

  linkA.appendChild(visible);
  linkB.appendChild(deleteBtn);

  //Loop through the webBooks

  for (let i = 0; i < 10; i++) {
    span.innerHTML = "test"+i+ " "; // Problem is here!

    li.appendChild(span);
    li.appendChild(linkA);
    li.appendChild(linkB);
    bookList.appendChild(li.cloneNode(true));
  }
<ul class="collection" id="web-book-list">
            <li class="collection-item">
              <span class="flow-text">item 1</span>
              <a href="#!" class="secondary-content"
                ><i class="small material-icons black-text">visibility</i></a
              >
              <a href="#!" class="secondary-content"
                ><i class="small material-icons red-text">delete_forever</i></a
              >
            </li>
            <li class="collection-item">
              <span class="flow-text">item 2</span>
              <a href="#!" class="secondary-content"
                ><i class="small material-icons black-text">visibility</i></a
              >
              <a href="#!" class="secondary-content"
                ><i class="small material-icons red-text">delete_forever</i></a
              >
            </li>
        </ul>
另一答案

您需要为循环中的每本书创建一个span元素。您还需要创建lis和链接。当您使用appendChild附加已经在文档中其他位置的元素时,它将被移动,而不是被复制。

由于您要在元素等上设置类,因此为循环的每次迭代创建单独的类的最简单方法是使用cloneNode

let bookList = document.getElementById("web-book-list");
// Create element
let li = document.createElement("li");
let span;                                    // *** No need to create one here
let linkA = document.createElement("a");
let linkB = document.createElement("a");

// ...

for (let i = 0; i < webBooks.length; i++) {
  console.log(webBooks[i]);
  const thisSpan = span.cloneNode(true);     // ***
  thisSpan.innerHTML = webBooks[i].name;     // *** No need for += since we're creating a new span

  const thisLi = li.clone(true);             // ***
  thisLi.appendChild(thisSpan);              // ***
  thisLi.appendChild(linkA.cloneNode(true)); // ***
  thisLi.appendChild(linkB.cloneNode(true)); // ***
  bookList.appendChild(thisLi);              // ***
}

我还建议不要将文本视为HTML,这是你在这里做的:

thisSpan.innerHTML = webBooks[i].name;

如果该名称中包含<(甚至是恶意脚本内容),那么将其视为HTML将是一个问题。代替:

thisSpan.appendChild(document.createTextNode(webBooks[i].name));

以上是关于坚持使用JS DOM Manipulation的主要内容,如果未能解决你的问题,请参考以下文章

Dom Manipulation - 改变 DOM [重复]

jQuery-DOM Manipulation

javascript Javascript DOM Manipulation可以提高性能

PHP DOM Manipulation 有啥用?

d3.js使用Class和Attr为文本添加颜色

Zombie.js 无法访问 DOM 元素的数据集属性