坚持使用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
元素。您还需要创建li
s和链接。当您使用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 [重复]