我正在添加到收藏夹功能。如果我单击一个图标,该图标旁边的品种将添加到点赞数组。我做了renderLikes函数,使数组出现在屏幕上。但是,只有一个品种出现可能是因为elements.favorite.innerHTML =''部分。如果我不写该部分,则每次单击图标时,整个数组都会继续添加到DOM树中。我有什么办法可以渲染数组中的每个项目,例如
item
item2
...?
另一个问题,如果我单击图标有时会向数组添加一个空元素。如何预防此问题?
<!DOCTYPE html>
<html lang="en">
<head>
<style>
ul {
list-style: none;
line-height: 1.6;
}
.icon {
display: inline-block;
width: 1em;
height: 1em;
stroke-width: 0;
stroke: currentColor;
fill: currentColor;
vertical-align: middle;
cursor: pointer;
transition: transform .3s;
transform: scale(0.8);
}
.icon:hover {
transform: scale(1.6) rotate(-15deg);
}
.icon-fill {
fill: red;
}
</style>
<title>Like Button Practice</title>
</head>
<body>
<ul class="list"></ul>
<h2>My Favorite Dogs</h2>
<div class="favorite">
</div>
<script>
const data = [
{
"breed": "Beagle",
"characteristics": "playful"
},
{
"breed": "Golden Retriever",
"characteristics": "calm"
},
{
"breed": "Corgi",
"characteristics": "bright"
},
{
"breed": "Goldendoodle",
"characteristics": "gentle"
},
{
"breed": "Labrador Retriever",
"characteristics": "loyal"
},
]
const elements = {
"icon": document.querySelectorAll('svg'),
"dom": document.querySelector('.list'),
"favorite": document.querySelector('.favorite')
}
const likes = [];
// Render method
function test() {
data.map(item => {
renderList(item.breed);
return item.breed;
})
};
test();
function renderList(dog) {
const markup = `
<li id="${dog}">
<svg class="icon icon-heart-outlined"><use xlink:href="icon/sprite.svg#icon-heart-outlined"></use></svg>
${dog}
</li>
`;
elements.dom.insertAdjacentHTML('beforeend', markup);
}
function renderLikes(item) {
const markup = `
<p>${item}</p>
`;
elements.favorite.innerHTML = '';
elements.favorite.insertAdjacentHTML('beforeend', markup);
}
elements.dom.addEventListener('click', e => {
const id = e.target.parentNode.id;
if (e.target.matches('.icon, .icon *')) {
// If (Beagle, Golden Retriever... does not exist in likes array, it returns -1)
const index = likes.indexOf(e.target.parentNode.id);
if (index === -1) {
likes.push(id);
console.log(likes);
likes.forEach(function( value ) {
console.log( value );
renderLikes(value);
});
} else {
likes.splice(index, 1);
}
}
});
</script>
</body>
</html>
答案 0 :(得分:1)
是的,innerHTML =''正在删除整个内容。
无论如何,您都应该使用数据并进行显示,请尽量不要将数据耦合到视图上。
我会解释...
您正在这样做:
这样做,您必须一次管理两种不同的逻辑,即渲染逻辑(在某物旁边绘画)和数据逻辑本身(在列表中添加或删除项目)。这导致不一致。 您应该管理数据,渲染逻辑应该显示数据。
我会这样做的。
通过这样做,您始终可以确保渲染与正在使用的模型一致。 启用后,您可以进行性能调整,例如虚拟dom,差异渲染等。但是一致性是最重要的。
我的代码如下:
const $likelist = document.querySelector('.likelist');
const likeTemplate = i => `<p>Whatever ... ${i} blah blah </p>`;
const renderLikes = () => $likelist.innerHTML = likes.map(i => likeTemplate(i)).join();
const addToLikelist = (el) => {
// Validate the item is valid and is not in the list yet
likes.push(el);
renderLikes();
}