对于此JavaScript问题,我真的很感激,因为我遇到的click事件在每次关闭滑块然后重新打开时都会增加一倍。
当您第一次打开滑块并单击幻灯片时,您可以在控制台中看到,每次单击“ btn--next”时,点击次数都会增加1,这当然是正确的。当我然后关闭滑块并单击“ btn--next”时再次将其重新打开时,控制台中的单击现在每次单击增加2。再次关闭滑块并重新打开,然后在每次重新加载滑块时,“ btn--next”在控制台中单击的次数增加3,依此类推。 https://jsfiddle.net/95afhtx8/2/
<?php
$generator = $con->prepare("SELECT idKategorie, Nazev, Kategorie_idKategorie FROM kategorie");
$generator->bind_result($id, $kategorie, $parent);
$generator->execute();
echo "<div class='contejner1' style='margin-top: 0px; margin-bottom: 0px;'>";
while($generator->fetch()){
if($parent == NULL){
echo "<div id='$kategorie' class='vliste' onmouseover='hoverkategorie($id)' onmouseout='unhoverkategorie($id)'>";
echo "$kategorie";
echo " </div>";
}
if($parent != NULL){
echo "<div id='$parent' class='podkategorie' onmouseover='hoverkategorie($parent)' onmouseout='unhoverkategorie($parent)'>";
echo "<div class='contejner1' style='margin-top: 0px; margin-bottom: 0px;'>";
echo "$kategorie";
echo "</div>";
echo "</div>";
}
}
echo "<div id='posledni' style='height: 20px; display: inline-block; vertical-align: middle; padding-left: 0px; padding-right: 0px;'>";
echo "</div>";
echo "</div>";
$generator->close();
?>
答案 0 :(得分:2)
这是因为每次您单击滑块切换器时:
function fizzBuzz(n) {
for (var i = 0; i <= n; i++) {
var printVal = "";
if (i % 3 === 0) {
printVal += "fizz";
}
if (i % 5 === 0) {
printVal += "buzz";
}
if (printVal === "") {
printVal = i;
}
console.log(printVal);
}
}
fizzBuzz(100);
您正在重新运行这样的代码,这将向元素添加另一个点击处理程序:
BillingCycle.aggregate([{
$project: {credit: {$sum: "$credits.value"}, debt: {$sum: "debts.value"}}
}, {
$group: {
_id: null,
credit: {$sum: "$credit"}, debt: {$sum: "debt"}
}
}, {
$project: {_id: 0, credit: 1, debt: 1 }
}]});
您可以将多个事件侦听器添加到DOM中的任何对象。因此,每次滑动滑块时,您只需不断添加更多内容即可。
您在这里有三个常规选项。
选项1:仅设置一次点击处理程序
请勿在{{1}}函数内重新添加事件处理程序。在外面做,这样就不必重新添加处理程序。
选项2:关闭时删除点击处理程序
您可以关闭关闭事件监听器。为此,您应该存储对所创建函数的引用,以便以后可以显式删除它。您应该对添加的所有处理程序执行此操作。
loadSlider[s].addEventListener('click', function () {
这样,当隐藏滑块时,单击功能将被关闭,然后重新打开它将添加新的单击处理程序,而旧的单击处理程序不会被触发,因为您将其删除了。
选项3:重新创建元素
如果您从DOM中删除一个元素并制作一个全新的元素,则新元素将不会具有过时的单击处理程序。这意味着您将需要使用Javascript动态构建标记(使用 nextSlide.addEventListener('click', function() {
),而不是将其存储在HTML页面主体中。
答案 1 :(得分:1)
在您的代码中,每次打开滑块时都调用nextSlide.addEventListener(...)
,但从不删除该侦听器。您必须在关闭滑块时调用函数nextSlide.removeEventListener(...)
。您也可以确保仅在第一次打开滑块时或什至在打开滑块之前才调用addEventListener
,因为html元素不会被破坏。
要删除监听器,必须在关闭滑块时使其在代码中可访问。您不能为此使用匿名函数。
编辑: 另一个更简单的解决方案是更改
nextSlide.addEventListener('click', function(){...});
收件人:
nextSlide['onclick'] = function() {...};
答案 2 :(得分:1)
我更新了代码以使其正常工作(您需要先声明第一个事件侦听器的匿名功能,然后再开始声明其他事件侦听器,否则您将一遍又一遍地复制它们,并因此倍增/四倍复制等)。我还建议将DOM选择器移到事件侦听器之外,它们只能进行一次评估:
var loadSlider = document.querySelector('.load__slider');
var slider = document.querySelector('.animal__slider');
var sliderSlide = document.querySelectorAll('.animal__slider__slide');
var nextSlide = document.querySelector('.btn--next');
var previousSlide = document.querySelector('.btn--previous');
var closeSlider = document.querySelector('.animal__slider__close');
var currentSlide = 0;
loadSlider.addEventListener('click', function() {
slider.classList.add('active');
setTimeout(function() {
slider.classList.add('active--show');
startSlide();
}, 100);
});
//Reset Slider
function resetSlides() {
for (var s = 0; s < sliderSlide.length; s++) {
sliderSlide[s].classList.remove('active--show');
sliderSlide[s].classList.remove('active');
}
}
//Start Slider
function startSlide() {
resetSlides();
sliderSlide[0].classList.add('active');
setTimeout(function() {
sliderSlide[0].classList.add('active--show');
}, 100);
}
//Previous slide
function slidePrevious() {
resetSlides();
sliderSlide[currentSlide - 1].classList.add('active');
setTimeout(function() {
sliderSlide[currentSlide].classList.add('active--show');
}, 100);
currentSlide--;
}
previousSlide.addEventListener('click', function() {
if (currentSlide === 0) {
currentSlide = sliderSlide.length;
}
console.log('click');
slidePrevious();
});
//Next slide
function slideNext() {
resetSlides();
sliderSlide[currentSlide + 1].classList.add('active');
setTimeout(function() {
sliderSlide[currentSlide].classList.add('active--show');
}, 100);
currentSlide++;
}
nextSlide.addEventListener('click', function() {
if (currentSlide === sliderSlide.length - 1) {
currentSlide = -1;
}
console.log('click');
slideNext();
});
closeSlider.addEventListener('click', function() {
slider.classList.remove('active--show');
slider.classList.remove('active');
resetSlides();
});
.animals {
text-align: center;
position: relative;
width: 80%;
height: 300px;
margin: 0 auto;
background-color: grey;
}
.load__slider {
text-align: center;
}
.animal__slider {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
display: none;
}
.animal__slider.active {
display: block;
}
.animal__slider.active .animal__slider__close {
display: block;
}
.animal__slider.active+.animal__slider__open {
opacity: 0;
}
.animal__slider__slide {
display: none;
position: absolute;
width: 100%;
height: 100%;
}
.animal__slider__slide1 {
background-color: red;
}
.animal__slider__slide2 {
background-color: green;
}
.animal__slider__slide3 {
background-color: yellow;
}
.animal__slider__slide4 {
background-color: blue;
}
.animal__slider__slide.active {
display: block;
}
.btn {
color: black;
position: absolute;
bottom: 5px;
cursor: pointer;
}
.btn--previous {
right: 60px;
}
.btn--next {
right: 30px;
}
.animal__slider__close {
display: none;
position: absolute;
right: 0;
cursor: pointer;
}
.animal__slider__open {
display: block;
cursor: pointer;
}
<section class="animals">
<div class="animal__slider">
Slider
<div class="animal__slider__slide animal__slider__slide1">
slide 1
</div>
<div class="animal__slider__slide animal__slider__slide2">
slide 2
</div>
<div class="animal__slider__slide animal__slider__slide3">
slide 3
</div>
<div class="animal__slider__slide animal__slider__slide4">
slide 4
</div>
<span class="btn btn--previous">previous</span>
<span class="btn btn--next">next</span>
<span class="animal__slider__close">close slider</span>
</div>
<span class="animal__slider__open load__slider">open slider</span>
</section>