Javascript Filter查找所有数据属性,但不查找它们各自的DOM元素



我构建了一个过滤器,它只会找到一个DOM元素,但不会超过一个。但是,过滤器会为每个DOM元素找到所有的数据属性。

我想知道为什么所有的DOM元素都没有被发现,但他们所有的数据属性?例如,作为数据属性的类别数组是正确构建的,但是如果存在多个DOM元素,则无法找到它们各自的DOM元素。

在错误中,每个类别只有一篇博客文章,这是不实际的,因为最好是在任何给定的类别中看到多篇博客文章。

"use strict";
const filterBtns = Array.from(document.querySelectorAll("button.btn"));
const itemTag = Array.from(document.querySelectorAll("div.item"));
function applyFilter() {
filterBtns.forEach((btn, idx) => {
btn.addEventListener("click", () => {
if (idx === 0) {
itemTag.forEach(item => {
item.style.border = 'solid 2px red';
})
} else {
itemTag.forEach(item => {
item.style.border = 'solid 2px transparent';
})
filterValues(itemTag, btn)
}
})
})
}
/*
Takes an array and button attributes as parameters
Builds a new array of the items attributes and filters
the button clicked attribute.
Loops over the itemTag array and if they match change the color
of the border.
*/
function filterValues(arr, btnData) {
let attributeArray = [];
let btnAttribute = btnData.getAttribute('data-filter');
for (let index = 0; index <= arr.length - 1; index++) {
attributeArray.push(arr[index].getAttribute('data-filter'));
}
// builds filtered array
const result = attributeArray.filter((value => {
return value.trim().includes(btnAttribute);
}))
itemTag.forEach(item => {
let itemAttribute = item.getAttribute('data-filter');
if (itemAttribute.includes(result)) {
item.style.border = '2px solid blue';
console.log(item);
}
})
console.log("Result Array ", result);
}
applyFilter();
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
/* CSS VARIABLES */
:root {
--blog-primary-color: #A4BEF3;
--blog-secondary-color: whitesmoke;
--blog-primary-text-color: #000000;
--blog-secondary-text-color: #fff;
--blog-primary-padding: 2em;
--blog-primary-margin: 2rem;
--blog-section-padding: 1em;
}
/* General Settings */
button {
border: none;
margin: 0;
}
a {
text-decoration: none;
}

/* Render CSS */
body {
font-family: system-ui, serif;
font-size: 32px;
line-height: 1.5;
background-color: #f9f0de;
color: #1f2839;
}
/* Navigation Bar Styling */
nav {
display: flex;
justify-content: space-between;
align-items: center;
padding-left: var(--blog-primary-padding);
padding-right: var(--blog-primary-padding);
padding-top: 0.7rem;
background-color: var(--blog-primary-color);
}
nav h1 {
font-size: 24px;
font-weight: bolder;
}
nav a.login-link {
font-size: 18px;
color: #000000;
font-weight: bold;
}
/* Main Section Styling *****/
main {
background-color: var(--blog-secondary-color);
height: 100%;
display: flex;
justify-content: space-around;
}
main aside {
height: 100%;
position: sticky;
top: 0;
left: 0;
width: 25%;
}
/* Button Aside Div */
main aside div {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: flex-start;
/* border: 2px solid red; */
height: 500px;
padding: var(--blog-primary-padding);
}
main aside div p.button-p {
color: red;
font-size: 18px;
font-weight: bolder;
color: #1f2839;
}
button.btn {
color: #1f2839;
font-size: 16px;
background-color: whitesmoke;
transition: background-color 300ms ease-in-out;
width: 100%;
text-align: left;
border-radius: 5px;
font-weight: bold;
padding: 0.4rem 1rem 0.4rem 1rem;
}
button.btn:hover {
background-color: var(--blog-primary-color);
cursor: pointer;
}
/* Section Blog Grid Styling */
section.blog-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 1rem;
margin-top: 0.7rem;
}
div.item {
width: 360px;
border: 2px solid transparent;
}
div.item img {
width: 100%;
object-fit: cover;
}
div.blog-title {
display: flex;
justify-content: space-between;
}
div.blog-title h2,
div.blog-title p {
font-size: 24px;
color: var(--blog-primary-text-color);
}
p.blog-p {
color: var(--blog-primary-text-color);
font-size: 18px;
font-weight: 400;
}
/* Add MOBILE SCREEN MEDIA QUERIES */
<main class="index-main">
<aside class="categories">
<div class="button-div">
<p class="button-p">Blog Categories</p>
<button data-filter="all" class="btn">All</button>
<button data-filter="category-a" class="btn">Show A</button>
<button data-filter="category-b" class="btn">Show B</button>
<button data-filter="category-c" class="btn">Show C</button>
</div>
</aside>
<section class="blog-grid">
<div data-filter="category-a" class="item">
<img loading="lazy" src="assets/img/300.png" alt="placeholder image">
<div class="blog-title">
<h2>Title</h2>
<p>finance</p>
</div>
<p class="blog-p">
first blog description
</p>
</div>
<div data-filter="category-b" class="item">
<img loading="lazy" src="assets/img/300.png" alt="placeholder image">
<div class="blog-title">
<h2>Breakfast Wrap</h2>
<p>Tech</p>
</div>
<p class="blog-p">
second blog description
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Asperiores voluptates, facilis quas rem
officiis sapiente fugit! Cumque adipisci quam optio repellendus neque voluptatum, nam ut
consequuntur blanditiis possimus quae veniam?
</p>
</div>
<div data-filter="category-c" class="category-c item">
<img loading="lazy" src="assets/img/300.png" alt="placeholder image">
<div class="blog-title">
<h2>Breakfast Wrap</h2>
<p>lifestyle</p>
</div>
<p class="blog-p">
third blog description
</p>
</div>
<div data-filter="category-a" class="item">
<img loading="lazy" src="assets/img/300.png" alt="placeholder image">
<div class="blog-title">
<h2>Breakfast Wrap</h2>
<p>finance</p>
</div>
<p class="blog-p">
fourth blog description
</p>
</div>
</section>
</main>

为获得最佳观看效果,请打开全屏

元素正在被找到。问题出在if (itemAttribute.includes(result)) {中,您将数组result传递给includes方法,该方法需要一个字符串。

因为它期望一个字符串,它将尝试将您的result数组转换为字符串,如果您有单个值,则可以工作,但是在result数组中有两个项目,您会得到一个坏结果。

我相信你的逻辑应该是另一种方式,你应该检查itemAttribute是否存在于result数组中。

if (result.includes(itemAttribute)) {

"use strict";
const filterBtns = Array.from(document.querySelectorAll("button.btn"));
const itemTag = Array.from(document.querySelectorAll("div.item"));
function applyFilter() {
filterBtns.forEach((btn, idx) => {
btn.addEventListener("click", () => {
if (idx === 0) {
itemTag.forEach(item => {
item.style.border = 'solid 2px red';
})
} else {
itemTag.forEach(item => {
item.style.border = 'solid 2px transparent';
})
filterValues(itemTag, btn)
}
})
})
}
/*
Takes an array and button attributes as parameters
Builds a new array of the items attributes and filters
the button clicked attribute.
Loops over the itemTag array and if they match change the color
of the border.
*/
function filterValues(arr, btnData) {
let attributeArray = [];
let btnAttribute = btnData.getAttribute('data-filter');
for (let index = 0; index <= arr.length - 1; index++) {
attributeArray.push(arr[index].getAttribute('data-filter'));
}
// builds filtered array
const result = attributeArray.filter((value => {
return value.trim().includes(btnAttribute);
}))
itemTag.forEach(item => {
let itemAttribute = item.getAttribute('data-filter');
if (result.includes(itemAttribute)) {
item.style.border = '2px solid blue';
console.log(item);
}
})
console.log("Result Array ", result);
}
applyFilter();
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}

/* CSS VARIABLES */
:root {
--blog-primary-color: #A4BEF3;
--blog-secondary-color: whitesmoke;
--blog-primary-text-color: #000000;
--blog-secondary-text-color: #fff;
--blog-primary-padding: 2em;
--blog-primary-margin: 2rem;
--blog-section-padding: 1em;
}

/* General Settings */
button {
border: none;
margin: 0;
}
a {
text-decoration: none;
}

/* Render CSS */
body {
font-family: system-ui, serif;
font-size: 32px;
line-height: 1.5;
background-color: #f9f0de;
color: #1f2839;
}

/* Navigation Bar Styling */
nav {
display: flex;
justify-content: space-between;
align-items: center;
padding-left: var(--blog-primary-padding);
padding-right: var(--blog-primary-padding);
padding-top: 0.7rem;
background-color: var(--blog-primary-color);
}
nav h1 {
font-size: 24px;
font-weight: bolder;
}
nav a.login-link {
font-size: 18px;
color: #000000;
font-weight: bold;
}

/* Main Section Styling *****/
main {
background-color: var(--blog-secondary-color);
height: 100%;
display: flex;
justify-content: space-around;
}
main aside {
height: 100%;
position: sticky;
top: 0;
left: 0;
width: 25%;
}

/* Button Aside Div */
main aside div {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: flex-start;
/* border: 2px solid red; */
height: 500px;
padding: var(--blog-primary-padding);
}
main aside div p.button-p {
color: red;
font-size: 18px;
font-weight: bolder;
color: #1f2839;
}
button.btn {
color: #1f2839;
font-size: 16px;
background-color: whitesmoke;
transition: background-color 300ms ease-in-out;
width: 100%;
text-align: left;
border-radius: 5px;
font-weight: bold;
padding: 0.4rem 1rem 0.4rem 1rem;
}
button.btn:hover {
background-color: var(--blog-primary-color);
cursor: pointer;
}

/* Section Blog Grid Styling */
section.blog-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 1rem;
margin-top: 0.7rem;
}
div.item {
width: 360px;
border: 2px solid transparent;
}
div.item img {
width: 100%;
object-fit: cover;
}
div.blog-title {
display: flex;
justify-content: space-between;
}
div.blog-title h2,
div.blog-title p {
font-size: 24px;
color: var(--blog-primary-text-color);
}
p.blog-p {
color: var(--blog-primary-text-color);
font-size: 18px;
font-weight: 400;
}

/* Add MOBILE SCREEN MEDIA QUERIES */
<main class="index-main">
<aside class="categories">
<div class="button-div">
<p class="button-p">Blog Categories</p>
<button data-filter="all" class="btn">All</button>
<button data-filter="category-a" class="btn">Show A</button>
<button data-filter="category-b" class="btn">Show B</button>
<button data-filter="category-c" class="btn">Show C</button>
</div>
</aside>
<section class="blog-grid">
<div data-filter="category-a" class="item">
<img loading="lazy" src="assets/img/300.png" alt="placeholder image">
<div class="blog-title">
<h2>Title</h2>
<p>finance</p>
</div>
<p class="blog-p">
first blog description
</p>
</div>
<div data-filter="category-b" class="item">
<img loading="lazy" src="assets/img/300.png" alt="placeholder image">
<div class="blog-title">
<h2>Breakfast Wrap</h2>
<p>Tech</p>
</div>
<p class="blog-p">
second blog description Lorem, ipsum dolor sit amet consectetur adipisicing elit. Asperiores voluptates, facilis quas rem officiis sapiente fugit! Cumque adipisci quam optio repellendus neque voluptatum, nam ut consequuntur blanditiis possimus quae veniam?
</p>
</div>
<div data-filter="category-c" class="category-c item">
<img loading="lazy" src="assets/img/300.png" alt="placeholder image">
<div class="blog-title">
<h2>Breakfast Wrap</h2>
<p>lifestyle</p>
</div>
<p class="blog-p">
third blog description
</p>
</div>
<div data-filter="category-a" class="item">
<img loading="lazy" src="assets/img/300.png" alt="placeholder image">
<div class="blog-title">
<h2>Breakfast Wrap</h2>
<p>finance</p>
</div>
<p class="blog-p">
fourth blog description
</p>
</div>
</section>
</main>

最新更新