使用 javascript 创建多个元素
Creating multiple elements with javascript
我有一个 html 元素树示例(如下),我想 return 为我在 database.Lets 中获得的每场比赛提供相关数据,假设有 5 场比赛。
我是否需要创建 5 个给定元素并用 javascript 数据填充它们?
我要 运行 一个循环,但这看起来会消耗性能(为每个匹配创建所有元素树)。相反,我可以使用给定的元素(图片)用 javascript 填充它并将其放到 dom 而不是(x 次)吗?如果可能怎么办?
<!-- sample elem -->
<div class="col-12 col-md-4" style="display: none">
<div class="card my-3 mx-1">
<a href="#"><img src="" alt="img"></a>
<div class="card-body">
<div class="row">
<div class="col-12 p-1">Country</div>
<div class="col-3 p-1">State</div>
<div class="col-4 p-1">City</div>
</div>
</div>
</div>
</div>
15-20 个元素和单独的标记对性能的影响不大。
然而,如果你能证明它很慢,就知道字符串更快。所以更快的方法是:
- 将标记模板存储为字符串
- 用最终标记创建一个字符串 - 它可以根据需要重复模板多次,显然用它填充
- 在目标节点中插入标记
这是它的样子:
const products = [{ title: 'gearbox' }, { title: 'drive shaft' }, { title: 'spark plug'}]
const myTemplate = '<div class="product">{title}</div>'
const finalMarkup = products.map(({ title }) => myTemplate.replace('{title}', title))
document.getElementId('targetNode').innerHtml = finalMarkup
进一步阐述我的评论:经常将元素重复插入到 DOM 树中会导致性能问题,因为每次插入新节点时文档都需要重排。你不应该担心 calling/invoking document.createElement()
太多次:那是你最不关心的事情。
因此,我建议您使用一个函数来创建您的整个示例元素。然后,您可以在循环的每次迭代中调用此函数来创建整个卡片元素,然后将其附加到文档片段。
伪代码:
function createCard() {
// Create the entire `sample element` as you would call it
const el = <something>;
return el;
}
// Create new document fragment to hold all the nodes
// At this point, we are NOT injecting them into the DOM yet
const fragment = new DocumentFragment();
// Go through your data and create new card for each data point
for (let i = 0; i < 5; i++) {
fragment.appendChild(createCard());
}
// Now this is when you insert the entire bulk of the content into the DOM
document.querySelector('#myInsertionTarget').appendChild(fragment);
概念验证代码如下:
// Since we are creating so many `<div>` elements
// It helps to further abstract its logic into another function
function createDivElement(classes, text) {
const div = document.createElement('div');
if (classes.length)
div.classList.add(...classes);
if (text)
div.innerText = text;
return div;
}
// Call this whenever you want to create a new card
function createCard(i) {
const colCountry = createDivElement(['col-12', 'p-1'], 'Country');
const colState = createDivElement(['col-3', 'p-1'], 'State');
const colCity = createDivElement(['col-4', 'p-1'], 'City');
const row = createDivElement(['row']);
row.appendChild(colCountry);
row.appendChild(colState);
row.appendChild(colCity);
const cardBody = createDivElement(['card-body']);
cardBody.appendChild(row);
const image = document.createElement('img');
image.alt = 'img';
// Proof-of-concept image source, you can ignore this!
image.src = `https://placehold.it/100x50?text=Image%20${i+1}`;
const imageLink = document.createElement('a');
imageLink.href = '#';
imageLink.appendChild(image);
const card = createDivElement(['card', 'my-3', 'mx-1']);
card.appendChild(imageLink);
card.appendChild(cardBody);
const outer = createDivElement(['col-12', 'col-md-4']);
// outer.style.display = 'none';
outer.appendChild(card);
return outer;
}
// Create new document fragment
const fragment = new DocumentFragment();
// In each iteration of the loop, insert the new card element into fragment
for (let i = 0; i < 5; i++) {
const el = createCard(i);
fragment.appendChild(el);
}
// When you're done generating the entire set of elements
// You can then insert the fragment into your DOM (finally!)
document.querySelector('#app').appendChild(fragment);
<div id="app"></div>
我有一个 html 元素树示例(如下),我想 return 为我在 database.Lets 中获得的每场比赛提供相关数据,假设有 5 场比赛。 我是否需要创建 5 个给定元素并用 javascript 数据填充它们?
我要 运行 一个循环,但这看起来会消耗性能(为每个匹配创建所有元素树)。相反,我可以使用给定的元素(图片)用 javascript 填充它并将其放到 dom 而不是(x 次)吗?如果可能怎么办?
<!-- sample elem -->
<div class="col-12 col-md-4" style="display: none">
<div class="card my-3 mx-1">
<a href="#"><img src="" alt="img"></a>
<div class="card-body">
<div class="row">
<div class="col-12 p-1">Country</div>
<div class="col-3 p-1">State</div>
<div class="col-4 p-1">City</div>
</div>
</div>
</div>
</div>
15-20 个元素和单独的标记对性能的影响不大。
然而,如果你能证明它很慢,就知道字符串更快。所以更快的方法是:
- 将标记模板存储为字符串
- 用最终标记创建一个字符串 - 它可以根据需要重复模板多次,显然用它填充
- 在目标节点中插入标记
这是它的样子:
const products = [{ title: 'gearbox' }, { title: 'drive shaft' }, { title: 'spark plug'}]
const myTemplate = '<div class="product">{title}</div>'
const finalMarkup = products.map(({ title }) => myTemplate.replace('{title}', title))
document.getElementId('targetNode').innerHtml = finalMarkup
进一步阐述我的评论:经常将元素重复插入到 DOM 树中会导致性能问题,因为每次插入新节点时文档都需要重排。你不应该担心 calling/invoking document.createElement()
太多次:那是你最不关心的事情。
因此,我建议您使用一个函数来创建您的整个示例元素。然后,您可以在循环的每次迭代中调用此函数来创建整个卡片元素,然后将其附加到文档片段。
伪代码:
function createCard() {
// Create the entire `sample element` as you would call it
const el = <something>;
return el;
}
// Create new document fragment to hold all the nodes
// At this point, we are NOT injecting them into the DOM yet
const fragment = new DocumentFragment();
// Go through your data and create new card for each data point
for (let i = 0; i < 5; i++) {
fragment.appendChild(createCard());
}
// Now this is when you insert the entire bulk of the content into the DOM
document.querySelector('#myInsertionTarget').appendChild(fragment);
概念验证代码如下:
// Since we are creating so many `<div>` elements
// It helps to further abstract its logic into another function
function createDivElement(classes, text) {
const div = document.createElement('div');
if (classes.length)
div.classList.add(...classes);
if (text)
div.innerText = text;
return div;
}
// Call this whenever you want to create a new card
function createCard(i) {
const colCountry = createDivElement(['col-12', 'p-1'], 'Country');
const colState = createDivElement(['col-3', 'p-1'], 'State');
const colCity = createDivElement(['col-4', 'p-1'], 'City');
const row = createDivElement(['row']);
row.appendChild(colCountry);
row.appendChild(colState);
row.appendChild(colCity);
const cardBody = createDivElement(['card-body']);
cardBody.appendChild(row);
const image = document.createElement('img');
image.alt = 'img';
// Proof-of-concept image source, you can ignore this!
image.src = `https://placehold.it/100x50?text=Image%20${i+1}`;
const imageLink = document.createElement('a');
imageLink.href = '#';
imageLink.appendChild(image);
const card = createDivElement(['card', 'my-3', 'mx-1']);
card.appendChild(imageLink);
card.appendChild(cardBody);
const outer = createDivElement(['col-12', 'col-md-4']);
// outer.style.display = 'none';
outer.appendChild(card);
return outer;
}
// Create new document fragment
const fragment = new DocumentFragment();
// In each iteration of the loop, insert the new card element into fragment
for (let i = 0; i < 5; i++) {
const el = createCard(i);
fragment.appendChild(el);
}
// When you're done generating the entire set of elements
// You can then insert the fragment into your DOM (finally!)
document.querySelector('#app').appendChild(fragment);
<div id="app"></div>