为什么 classList 会返回错误:Uncaught TypeError: Cannot read properties of undefined (reading 'classList')?
我不明白为什么会出现错误: 未捕获的类型错误:无法读取未定义的属性(读取“classList”) console.log(slid[numberArray].classList)- 可以工作,但是 slid[numberArray].classList.add('active') - 无法工作 我知道这不是一个好的代码,但我仍在学习,我想自己制作一个滑块
const slid = [...document.querySelectorAll('.slid')];
const arrows = document.querySelectorAll('.arrows-slider .arrow');
slid.forEach(s => {
if( s.classList.contains('active') == false){
s.style.opacity = '0';
}
});
arrows.forEach( arrow =>{
arrow.addEventListener('click', function(){
if(this.classList.contains('arrows-right')){
slid.forEach(s => {
if( s.classList.contains('active')){
s.classList.remove('active');
let numberArray = slid.indexOf(s);
numberArray ++;
slid[numberArray].classList.add('active');
console.log(slid[numberArray].classList);
}
});
}else if( this.classList.contains('arrows-left')){
}
});
});
.slider {
position: absolute;
top: 0;
left: 0;
width: 100%;
background-image: url('../img/mirrored_squares.png');
height: 100vh;
}
.slid {
position: absolute;
width: 100%;
height: 100vh;
opacity: 0;
}
.active {
opacity: 1 !important;
}
.img-slid {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 35%;
height: 50%;
background-size: cover;
}
.engine {
background-image: url("../img/silnik.jpg");
}
.exhaust {
background-image: url("../img/wydech.jpg");
}
.slid-text {
position: absolute;
top: 50%;
left: 11%;
transform: translateY(-50%);
font-size: 8rem;
text-transform: uppercase;
color: #fff;
font-family: 'Black Ops One', cursive;
}
.number-slaid {
position: absolute;
bottom: 8%;
right: 8%;
font-size: 2rem;
color: #fff;
font-family: 'Black Ops One', cursive;
}
/* .arrows-left {
position: absolute;
top: 50%;
left: 5%;
transform: translateY(-50%);
}
.line-arrow {
width: 2px;
height: 70px;
background-color: black;
}
.top-line {
transform: rotate(48deg) translateY(25%);
}
.bottom-line {
transform: rotate(-48deg) translateY(-25%);
} */
.arrows-left {
position: absolute;
top: 50%;
left: 5%;
transform: translateY(-50%) rotate(45deg);
}
.arrows-right {
position: absolute;
top: 50%;
right: 5%;
transform: translateY(-50%) rotate(-135deg);
}
.arrow {
width: 80px;
height: 80px;
border-left: 2px solid #000;
border-bottom: 2px solid #000;
cursor: pointer;
}
<section class="slider">
<div class="slid slid1 active">
<div class="engine img-slid"> </div>
<p class="slid-text">engine</p>
<p class="number-slaid">01</p>
</div>
<div class="slid slid2 ">
<div class="exhaust img-slid"></div>
<p class="slid-text">exhaust</p>
<p class="number-slaid">02</p>
</div>
<div class="arrows-slider">
<div class="arrows-left arrow"></div>
<div class="arrows-right arrow"></div>
</div>
</section>
首先,在您的场景中使用
Array.forEach()
通常不是一个好主意,因为即使您的工作已在第一个元素上完成,它也会遍历整个列表。因此,我强烈建议您使用可以中断的循环。因为在设置下一个
element.classList.active
后,列表就没有必要继续了。
您的第二个错误正如 David 所解释的那样,在到达列表的最后一个元素时没有重置回位置
0
。
这是一个有效示例。我在一个代码中合并了
arrows-right
和
arrows-left
事件行为。
const slid = [...document.querySelectorAll('.slid')];
const arrows = document.querySelectorAll('.arrows-slider .arrow');
arrows.forEach( arrow =>
{
arrow.addEventListener('click', function(clickEvent)
{
var target = clickEvent.currentTarget;
for(let i = 0; i < slid.length; i++)
{
if( slid[i].classList.contains('active'))
{
slid[i].classList.remove('active');
let numberArray;
if(target.classList.contains("arrows-right"))
{
numberArray = 0;
i++;
} else
{
numberArray = slid.length - 1;
i--;
}
if(slid[i] === undefined)
slid[numberArray].classList.add('active');
else
slid[i].classList.add('active');
break;
}
}
});
});
.slider {
position: absolute;
top: 0;
left: 0;
width: 100%;
background-image: url('../img/mirrored_squares.png');
height: 100vh;
}
.slid {
position: absolute;
width: 100%;
height: 100vh;
opacity: 0;
display: none;
}
.slid.active {
opacity: 1;
display: block;
}
.img-slid {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 35%;
height: 50%;
background-size: cover;
}
.engine {
background-image: url("../img/silnik.jpg");
}
.exhaust {
background-image: url("../img/wydech.jpg");
}
.slid-text {
position: absolute;
top: 50%;
left: 11%;
transform: translateY(-50%);
font-size: 8rem;
text-transform: uppercase;
color: green;
font-family: 'Black Ops One', cursive;
}
.number-slaid {
position: absolute;
bottom: 8%;
right: 8%;
font-size: 2rem;
color: #fff;
font-family: 'Black Ops One', cursive;
}
/* .arrows-left {
position: absolute;
top: 50%;
left: 5%;
transform: translateY(-50%);
}
.line-arrow {
width: 2px;
height: 70px;
background-color: black;
}
.top-line {
transform: rotate(48deg) translateY(25%);
}
.bottom-line {
transform: rotate(-48deg) translateY(-25%);
} */
.arrows-left {
position: absolute;
top: 50%;
left: 5%;
transform: translateY(-50%) rotate(45deg);
}
.arrows-right {
position: absolute;
top: 50%;
right: 5%;
transform: translateY(-50%) rotate(-135deg);
}
.arrow {
width: 80px;
height: 80px;
border-left: 2px solid #000;
border-bottom: 2px solid #000;
cursor: pointer;
}
<section class="slider">
<div class="slid slid1 active">
<div class="engine img-slid"> </div>
<p class="slid-text">engine</p>
<p class="number-slaid">01</p>
</div>
<div class="slid slid2 ">
<div class="exhaust img-slid"></div>
<p class="slid-text">exhaust</p>
<p class="number-slaid">02</p>
</div>
<div class="slid slid3 ">
<div class="smoke img-slid"></div>
<p class="slid-text">smoke</p>
<p class="number-slaid">03</p>
</div>
<div class="arrows-slider">
<div class="arrows-left arrow"></div>
<div class="arrows-right arrow"></div>
</div>
</section>
当循环遍历
slid
数组时,您将
s
定义为该数组中的每个元素:
slid.forEach(s => {
然后,您将
numberArray
定义为该元素在该数组中的索引:
let numberArray = slid.indexOf(s);
然后,您增加
numberArray
:
numberArray ++;
然后访问该新索引处的元素:
slid[numberArray].classList.add('active');
那么,当
s
是数组的最后一个元素时会发生什么?
numberArray
将是该元素的索引,然后您将其增加到
最后一个元素
之后的元素的索引。不存在这样的元素,因此此时
slid[numberArray]
为
undefined
。
到达数组末尾后,您想如何处理?无论您想如何处理,您都可以在那里实现该逻辑。
例如,如果您想在到达最后一个元素时从数组的开头重新开始,您可以检查是否位于数组末尾并重置为
0
:
let numberArray = slid.indexOf(s);
numberArray ++;
if (numberArray >= slid.length) {
numberArray = 0;
}
slid[numberArray].classList.add('active');