我有一个关于通过单击多个按钮在页面上显示多个类别的问题。代码笔: https://codepen.io/alena-chuyankova/pen/YzmWYKZ
let products = {
data: [
{
productName: "Fantasy",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Salmon, Shrimp",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-diego-pontes-901015-2323391.jpg",
},
{
productName: "Spring",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Veggie",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-pixabay-357756.jpg",
},
{
productName: "Rainbow",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Salmon, Tuna, Unagi",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-freestockpro-3147493.jpg",
},
{
productName: "Unique",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Salmon, Tuna, Unagi, Shrimp",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-photo-248444.webp",
},
{
productName: "Perfection",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Salmon",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-isabella-mendes-107313-858501.jpg",
},
{
productName: "Style",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Salmon, Tuna, Unagi, Shrimp",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-rajesh-tp-749235-2098143.jpg",
},
{
productName: "Dreamy",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Salmon",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-viniciusbenedit-3620705.jpg",
},
{
productName: "Spicy",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Shrimp",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-catscoming-699544.jpg",
},
],
};
for (let i of products.data) {
let card = document.createElement("div");
card.classList.add("card", "i.category");
//image
let imgContainer = document.createElement("div");
imgContainer.classList.add("image-container");
let image = document.createElement("img");
image.classList.add("product-img");
image.setAttribute("src", i.picture);
imgContainer.appendChild(image);
card.appendChild(imgContainer);
document.getElementById("products").appendChild(card);
card.setAttribute("title", i.category);
image.addEventListener("error", () => {
image.style.display = "none"; // Hide the broken image
image.parentNode.style.backgroundColor = "#d9d9d9"; // Set background color
});
//content
let content = document.createElement("div");
content.classList.add("content");
card.appendChild(content);
//content title and likes section
let contentHead = document.createElement("div");
contentHead.classList.add("contentHead");
let productTitle = document.createElement("h2");
productTitle.classList.add("productTitle");
productTitle.innerText = i.productName;
let likesSection = document.createElement("div");
likesSection.classList.add("likesSection");
let likesIcon = document.createElement("img");
likesIcon.setAttribute("src", "./icons/heart.svg");
likesIcon.classList.add("likesIcon");
let likesCount = document.createElement("p");
likesCount.classList.add("likeCount");
likesCount.innerText = i.heartCount;
content.appendChild(contentHead);
contentHead.appendChild(productTitle);
contentHead.appendChild(likesSection);
likesSection.appendChild(likesIcon);
likesSection.appendChild(likesCount);
likesIcon.addEventListener("error", () => {
likesIcon.setAttribute(
"src",
"https://upload.wikimedia.org/wikipedia/commons/f/f1/Heart_coraz%C3%B3n.svg"
);
});
//gray line devider
let line = document.createElement("hr");
line.classList.add("product-line");
content.appendChild(line);
//item category
let itemCategory = document.createElement("p");
itemCategory.classList.add("item-category");
itemCategory.innerText = i.category;
content.appendChild(itemCategory);
//description
let itemDescription = document.createElement("p");
itemDescription.classList.add("itemDescription");
itemDescription.innerText = i.content;
content.appendChild(itemDescription);
//read more
let readMore = document.createElement("p");
readMore.classList.add("readMore");
readMore.innerText = "Read more >>>";
content.appendChild(readMore);
}
let buttons = document.querySelectorAll(".category-button");
let cards = document.querySelectorAll(".card");
let buttonArr = [];
let buttonsString;
buttons.forEach((button) => {
button.addEventListener("click", () => {
let buttonValue = button.innerText;
button.classList.toggle("active-button");
if (button.classList.contains("active-button")) {
buttonArr.push(buttonValue);
}
if (button.classList.contains("active-button") == false) {
let unwantedButtonValue = buttonValue;
let index = buttonArr.indexOf(unwantedButtonValue);
buttonArr.splice(index, 1);
}
buttonArr.sort();
buttonsString = buttonArr.toString();
console.log(buttonsString);
});
buttons.forEach((button) => {
button.addEventListener("click", () => {
cards.forEach((card) => {
let cardCategories;
cardCategories = card
.getAttribute("title")
.split(",")
.map(function (value) {
return value.trim();
})
.sort()
.toString();
console.log(cardCategories);
if (cardCategories.includes(buttonsString) == false) {
card.classList.add("inactive-card");
}
if (cardCategories.includes(buttonsString)) {
card.classList.remove("inactive-card");
}
});
});
});
});
问题出在比较两个字符串的这段代码中。它适用于单一类别,因为例如“鲑鱼”包含在“鲑鱼、金枪鱼、虾”中。它因两个类别而失败,因为“鲑鱼,虾”不包含在“鲑鱼,金枪鱼,虾”中。词序不一样。
if (cardCategories.includes(buttonsString) == false) {
card.classList.add("inactive-card");
}
if (cardCategories.includes(buttonsString)) {
card.classList.remove("inactive-card");
}
您可以轻松解决此问题,因为您已经拥有一系列按钮类别。 因此,您可以使用 Array.some 显示包含任何关键字的卡片,或使用 Array.every 显示所有关键字(似乎您想要 every)。并且您可以使用 classList.toggle 根据比赛结果设置类别。
将上述代码替换为以下过滤器之一:
(并注意前导“!”不在切换逻辑中)
// (1) OR - card includes any keyword
card.classList.toggle(
'inactive-card',
!buttonArr.some(name => cardCategories.includes(name)) // boolean
)
// (2) AND - card include all keywords
card.classList.toggle(
'inactive-card',
!buttonArr.every(name => cardCategories.includes(name)) // boolean
)
let products = {
data: [
{
productName: "Fantasy",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Salmon, Shrimp",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-diego-pontes-901015-2323391.jpg",
},
{
productName: "Spring",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Veggie",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-pixabay-357756.jpg",
},
{
productName: "Rainbow",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Salmon, Tuna, Unagi",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-freestockpro-3147493.jpg",
},
{
productName: "Unique",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Salmon, Tuna, Unagi, Shrimp",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-photo-248444.webp",
},
{
productName: "Perfection",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Salmon",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-isabella-mendes-107313-858501.jpg",
},
{
productName: "Style",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Salmon, Tuna, Unagi, Shrimp",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-rajesh-tp-749235-2098143.jpg",
},
{
productName: "Dreamy",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Salmon",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-viniciusbenedit-3620705.jpg",
},
{
productName: "Spicy",
heart: "./icons/heart.svg",
heartCount: 2547,
category: "Shrimp",
content:
"Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
picture: "./images/pexels-catscoming-699544.jpg",
},
],
};
for (let i of products.data) {
let card = document.createElement("div");
card.classList.add("card", "i.category");
//image
let imgContainer = document.createElement("div");
imgContainer.classList.add("image-container");
let image = document.createElement("img");
image.classList.add("product-img");
image.setAttribute("src", i.picture);
imgContainer.appendChild(image);
card.appendChild(imgContainer);
document.getElementById("products").appendChild(card);
card.setAttribute("title", i.category);
image.addEventListener("error", () => {
image.style.display = "none"; // Hide the broken image
image.parentNode.style.backgroundColor = "#d9d9d9"; // Set background color
});
//content
let content = document.createElement("div");
content.classList.add("content");
card.appendChild(content);
//content title and likes section
let contentHead = document.createElement("div");
contentHead.classList.add("contentHead");
let productTitle = document.createElement("h2");
productTitle.classList.add("productTitle");
productTitle.innerText = i.productName;
let likesSection = document.createElement("div");
likesSection.classList.add("likesSection");
let likesIcon = document.createElement("img");
likesIcon.setAttribute("src", "./icons/heart.svg");
likesIcon.classList.add("likesIcon");
let likesCount = document.createElement("p");
likesCount.classList.add("likeCount");
likesCount.innerText = i.heartCount;
content.appendChild(contentHead);
contentHead.appendChild(productTitle);
contentHead.appendChild(likesSection);
likesSection.appendChild(likesIcon);
likesSection.appendChild(likesCount);
likesIcon.addEventListener("error", () => {
likesIcon.setAttribute(
"src",
"https://upload.wikimedia.org/wikipedia/commons/f/f1/Heart_coraz%C3%B3n.svg"
);
});
//gray line devider
let line = document.createElement("hr");
line.classList.add("product-line");
content.appendChild(line);
//item category
let itemCategory = document.createElement("p");
itemCategory.classList.add("item-category");
itemCategory.innerText = i.category;
content.appendChild(itemCategory);
//description
let itemDescription = document.createElement("p");
itemDescription.classList.add("itemDescription");
itemDescription.innerText = i.content;
content.appendChild(itemDescription);
//read more
let readMore = document.createElement("p");
readMore.classList.add("readMore");
readMore.innerText = "Read more >>>";
content.appendChild(readMore);
}
let buttons = document.querySelectorAll(".category-button");
let cards = document.querySelectorAll(".card");
let buttonArr = [];
let buttonsString;
buttons.forEach((button) => {
button.addEventListener("click", () => {
let buttonValue = button.innerText;
button.classList.toggle("active-button");
if (button.classList.contains("active-button")) {
buttonArr.push(buttonValue);
}
if (button.classList.contains("active-button") == false) {
let unwantedButtonValue = buttonValue;
let index = buttonArr.indexOf(unwantedButtonValue);
buttonArr.splice(index, 1);
}
buttonArr.sort();
buttonsString = buttonArr.toString();
console.log(buttonsString);
cards.forEach((card) => {
let cardCategories;
cardCategories = card
.getAttribute("title")
.split(",")
.map(function (value) {
return value.trim();
})
.sort()
.toString();
// ADDED
// OR - card includes any keyword
/*
card.classList.toggle(
'inactive-card',
!buttonArr.some(name => cardCategories.includes(name))
)
*/
// AND - card include all keywords
card.classList.toggle(
'inactive-card',
!buttonArr.every(name => cardCategories.includes(name))
)
/* REMOVED
if (cardCategories.includes(buttonsString) == false) {
card.classList.add("inactive-card");
}
if (cardCategories.includes(buttonsString)) {
card.classList.remove("inactive-card");
}
*/
});
});
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
font-family: 'Roboto', sans-serif;
background-color: #EEEEEE;
}
.wrap {
position: absolute;
top: 50%;
transform: translate(0, -50%);
background-color: white;
gap: 1rem;
width: 45%;
box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
display: flex;
flex-direction: column;
padding: 4rem;
}
.logo-phrase {
color: #FF3D00;
text-align: center;
}
.logo-phrase-red {
color: white;
background-color: #FF3D00;
}
.hr-h1 {
width: 10%;
align-self: center;
border: 1px solid #d9d9d9;
margin-bottom: 1rem;
}
.nav-buttons {
display: flex;
justify-content: center;
gap: 2rem;
}
.category-button {
display: flex;
padding: 1rem 2rem;
font-size: 1.3rem;
border-radius: 0.8rem;
border: 1.5px solid #FF3D00;
color: #FF3D00;
background-color: white;
font-weight: 500;
}
.active-button {
background-color: #FF3D00;
color: white;
}
#products {
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 1rem;
}
.card {
width: 100%;
display: flex;
gap: 1.5rem;
background-color: white;
margin-top: 1rem;
padding: 1rem;
}
.active-card {
display: flex;
}
.inactive-card {
display: none;
}
.image-container {
width: 35%;
text-align: center;
border-radius: 1rem;
}
.product-img {
background-color: #d9d9d9;
width: 100%;
border-radius: 1rem;
height: 10.5rem;
object-fit: cover;
padding: 1px;
}
.content {
width: 65%;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.contentHead {
width: 100%;
display: flex;
justify-content: space-between;
}
.likesSection {
display: flex;
width: 15%;
justify-content: space-between;
}
.likesIcon {
width: 20%;
align-self: center;
}
.likeCount {
color: #FF3D00;
align-self: center;
font-weight: bold;
}
.product-line {
border: 1px solid #d9d9d9;
}
.item-category {
font-weight: bold;
}
.readMore {
font-weight: bold;
color: #FF3D00;
}
@media screen and (max-width: 3500px) {
.wrap {
width: 65%;
}
}
@media screen and (max-width: 2500px) {
.wrap {
width: 75%;
}
}
@media screen and (max-width: 2100px) {
.wrap {
position: static;
top: 15%;
transform: none;
margin: 2rem 0;
width: 85%;
}
}
@media screen and (max-width: 1700px) {
.wrap {
width: 95%;
}
}
@media screen and (max-width: 1100px) {
.wrap {
margin: 2rem 0;
max-width: 50%;
justify-self: center;
}
.nav-buttons {
display: flex;
flex-wrap: wrap;
gap: 1rem;
width: 80%;
justify-self: center;
align-self: center;
}
.category-button {
flex-grow: 1;
}
#products {
display: grid;
grid-template-columns: 1fr;
grid-column-gap: 1rem;
width: 100%;
}
.card {
justify-self: center;
flex-direction: column;
width: 80%;
padding: 0;
padding-top: 1rem;
}
.card:first-child {
padding-top: 0;
}
.image-container {
width: 100%;
height: 15rem;
}
.product-img {
height: 15rem;
}
.content {
width: 100%;
}
}
@media screen and (max-width: 1100px) {
.wrap {
max-width: 60%;
}
}
@media screen and (max-width: 1000px) {
.wrap {
max-width: 65%;
}
}
@media screen and (max-width: 1000px) {
.wrap {
max-width: 65%;
}
}
@media screen and (max-width: 900px) {
.wrap {
max-width: 70%;
}
}
@media screen and (max-width: 800px) {
.wrap {
max-width: 75%;
}
}
@media screen and (max-width: 700px) {
.wrap {
max-width: 100%;
}
.image-container {
height: 12rem;
}
.product-img {
height: 12rem;
}
}
<div class="wrap">
<h1 class="logo-phrase">SayHiSus<span class="logo-phrase-red">Hi</span></h1>
<hr class="hr-h1">
<nav class="nav-buttons">
<button class="category-button">Salmon</button>
<button class="category-button">Tuna</button>
<button class="category-button">Unagi</button>
<button class="category-button">Shrimp</button>
<button class="category-button">Veggie</button>
</nav>
<div id="products"></div>
</div>