我有一个包含 6 个子框的 div(.game-space),其中一个是具有绿色背景的 ('.active-Box) 类的活动框,
所以当我点击活动框时,它会将它的类(.active-Box)移动到下一个给出绿色背景的框,这样它就会一直到最后一个框。我也有重新启动按钮,当我点击它时,游戏应该重新启动,就像活动框类被标记到第一个框,然后从这里它再次转移到下一个框,并在点击时一直到结束框。
'use strict'
const allBox = document.querySelectorAll('.box');
const activeBox = document.querySelector('.active-box')
const restartButton = document.querySelector('.restart-button')
let active_box_index = activeBox_index_function();
slideBox(allBox[active_box_index]);
/* ======> code1 Anonymous function */
/*
function slideBox(pass_active_box) {
pass_active_box.addEventListener('click', function() {
allBox[active_box_index].classList.remove('active-box')
allBox[active_box_index + 1].classList.add('active-box')
active_box_index = activeBox_index_function()
slideBox(allBox[active_box_index]);
})
} */
/* ======> code 2 , funtion defined oustside nad passed into EventListener*/
function sliderfunction() {
allBox[active_box_index].classList.remove('active-box')
allBox[active_box_index + 1].classList.add('active-box')
active_box_index = activeBox_index_function()
slideBox(allBox[active_box_index]);
}
function slideBox(pass_active_box) {
pass_active_box.addEventListener('click', sliderfunction);
}
// active box index
function activeBox_index_function() {
let index;
allBox.forEach((el, indx) => {
if (el.matches('.active-box')) {
index = indx
};
})
return index;
}
// when restart button clicked
restartButton.addEventListener('click', function () {
allBox[active_box_index].classList.remove('active-box')
allBox[0].classList.add('active-box')
active_box_index = activeBox_index_function()
})
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,800&display=swap');
@import url('https://fonts.cdnfonts.com/css/common-pixel');
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
html {
font-size: 62.5%;
font-family: 'Poppins', sans-serif;
color: black;
}
.game--section {
height: 100vh;
background-color: #252525;
display: flex;
justify-content: center;
align-items: center;
}
.game-space {
width: 80rem;
height: 10rem;
padding: 1rem;
border-radius: 9px;
background-color: #f5f5f5;
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 1rem;
}
.box {
background-color: tomato;
}
.active-box {
background-color: #099268;
cursor: pointer;
}
.restart-button {
font-size: 3rem;
cursor: pointer;
}
<body>
<section class="game--section">
<div class="game-space">
<div class="box box1 active-box"></div>
<div class="box box2"></div>
<div class="box box3"></div>
<div class="box box4"></div>
<div class="box box5"></div>
<div class="box box6"></div>
</div>
<div class="restart-button">🔁</div>
</section>
<script src="script.js"></script>
</body>
转折来了 我尝试将相同的代码块作为匿名函数传递给 addEventListener,并将外部定义的函数传递给 addEventListener。我看到两者的工作方式不同,其中\
code1) 匿名功能块正在向 DOM 元素添加增量 EventListener,因为双事件触发,它会跳过这些框。 code2)它没有增加 DOM 元素上的 EventListener,它工作得很好,我什至没有添加 removeEventListener 不是 DOM 元素。
一次,尝试关闭 code1 和 code2 的注释,反之亦然,在将活动框类移动到下一个框 2 到 3 次后,单击重新启动并尝试单击它们,你会得到我所怀疑的......
似乎当您尝试再次向事件侦听器添加已定义的函数时,它不会被添加,而匿名函数是真正匿名的,当您尝试再次向事件侦听器添加相同的代码时,引擎不会将其识别为与以前的功能相同,因此添加了多个事件侦听器。有关更多信息,请参阅MDN Web Docs。
上面写着:
如果函数或对象已经在事件监听器列表中 对于这个目标,函数或对象不会被第二次添加。
和:
如果一个特定的匿名函数在事件监听器列表中 为某个目标注册,然后在代码中,一个 在 addEventListener 调用中给出相同的匿名函数, 第二个函数也将添加到事件侦听器列表中 那个目标。
事实上,即使使用定义,匿名函数也不相同 重复调用相同的不变源代码,即使在循环中也是如此。
我的英语真的很糟糕,但如果我理解你的问题...
你有问题
sliderfunction()
你不检查
allBox[active_box_index + 1]
是否存在
所以你可以在
sliderfunction()
或activeBox_index_function()
中检查这个
在下面的代码片段中检查
sliderfunction()
,这样你就可以避免日志:
allBox[(active_box_index + 1)] is undefined"
在这种情况下,当您到达框的末尾时,最后一个框将保持活动状态,直到您单击开始按钮。
'use strict'
const allBox = document.querySelectorAll('.box');
const activeBox = document.querySelector('.active-box')
const restartButton = document.querySelector('.restart-button')
let active_box_index = activeBox_index_function();
slideBox(allBox[active_box_index]);
/* ======> code1 Anonymous function */
/*
function slideBox(pass_active_box) {
pass_active_box.addEventListener('click', function() {
allBox[active_box_index].classList.remove('active-box')
allBox[active_box_index + 1].classList.add('active-box')
active_box_index = activeBox_index_function()
slideBox(allBox[active_box_index]);
})
} */
/* ======> code 2 , funtion defined oustside nad passed into EventListener*/
function sliderfunction() {
//
allBox[active_box_index].classList.remove('active-box')
if((allBox[active_box_index + 1]!=undefined)){
allBox[active_box_index + 1].classList.add('active-box')
}else{
allBox[allBox.length-1].classList.add('active-box')
}
active_box_index = activeBox_index_function()
slideBox(allBox[active_box_index]);
}
function slideBox(pass_active_box) {
pass_active_box.addEventListener('click', sliderfunction);
}
// active box index
function activeBox_index_function() {
let index;
allBox.forEach((el, indx) => {
if (el.matches('.active-box')) {
index = indx
};
})
return index;
}
// when restart button clicked
restartButton.addEventListener('click', function () {
allBox[active_box_index].classList.remove('active-box')
allBox[0].classList.add('active-box')
active_box_index = activeBox_index_function()
})
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
html {
font-size: 62.5%;
font-family: 'Poppins', sans-serif;
color: black;
}
.game--section {
height: 100vh;
background-color: #252525;
display: flex;
justify-content: center;
align-items: center;
}
.game-space {
width: 80rem;
height: 10rem;
padding: 1rem;
border-radius: 9px;
background-color: #f5f5f5;
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 1rem;
}
.box {
background-color: tomato;
}
.active-box {
background-color: #099268;
cursor: pointer;
}
.restart-button {
font-size: 3rem;
cursor: pointer;
}
<section class="game--section">
<div class="game-space">
<div class="box box1 active-box"></div>
<div class="box box2"></div>
<div class="box box3"></div>
<div class="box box4"></div>
<div class="box box5"></div>
<div class="box box6"></div>
</div>
<div class="restart-button">🔁</div>
</section>