JavaScript:多个持久索引变量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript:多个持久索引变量相关的知识,希望对你有一定的参考价值。

我是编程世界的新手,在使用JS制作照片库方面遇到了一些麻烦。

因此,缩略图调用具有适当图像的模态,该图像通过索引作为参数传递。我使用了一些JQuery只是为了在没有循环的情况下在所有缩略图上附加处理程序。

第一个Modal初始化工作正常,我能够在图像之间切换,然后关闭模态就好了。之后,如果我重新初始化模态,第一个图像显示正确,但使用“下一个”和“上一个”按钮时,另一个图像出现在模态中。经过仔细检查(以及一堆变量日志)后,我确定旧的索引(来自第一个模态初始化)在程序中持续存在,因此该函数正在运行上一个索引并且新的索引传递给它。关闭它的次数越多,您拥有的索引变量就越多。几乎看起来该函数正在运行自身的多个副本,并将所有这些图像附加到该模态上。

对不起,如果这是一个非常明显的错误。我不是真的在这个论坛上发帖但是试着自己解决它,但是在6小时和50个Chrome标签之后,我就差不多了。非常感谢!这是我的代码:

https://jsfiddle.net/5yejqw8a/4/#&togetherjs=M77M8B8LU8

    $(document).ready(function(){

  $('.GalleryImg').on('click', function() { //Attach event handler on each photo
    var GalleryImgs = Array.prototype.slice.call(document.getElementsByClassName('GalleryImg')); //Turns object array to an a proper array
    var ImgIndex = GalleryImgs.indexOf(this); //Position of img clicked
    OpenModal(ImgIndex); //Passes the index into the modal function
  });

  function OpenModal(n) { //Modal function with index parameter
    var SlideIndex = n;
    console.log("Start Index = "+SlideIndex);
    var Lightbox = document.getElementById("Lightbox");
    var Modal = document.getElementById("ModalContent");
    var Slides = document.getElementsByClassName("ModalSlides");

    Lightbox.style.display = "block";
    Slides[SlideIndex].style.display = "block";

    var PreviousBtn = document.getElementById("PreviousBtn");
    PreviousBtn.addEventListener('click', function() {
      if (SlideIndex > 0) {
        Slides[SlideIndex].style.display = "none";
        SlideIndex --;
        Slides[SlideIndex].style.display = "block";
        console.log("PCurrent = "+SlideIndex);
      } else {
        return;
      };
    });

    var NextBtn = document.getElementById("NextBtn");
    NextBtn.addEventListener('click', function() {
      if (SlideIndex < Slides.length-1) {
        console.log(SlideIndex);
        Slides[SlideIndex].style.display = "none";
        SlideIndex ++;
        Slides[SlideIndex].style.display = "block";
        console.log("NCurrent = "+SlideIndex);
      } else {
        return;
      };
    });

    var CloseBtn = document.getElementById("CloseBtn");
    CloseBtn.addEventListener('click', function() {
      Lightbox.style.display = "none";
      var i = 0;
      while (i < Slides.length) {
        Slides[i].style.display = "none";
        i++
      };
      console.log("Closing Index = "+SlideIndex);
    });

  };

});
答案

你是因为这种结构而得到的:

function OpenModal(n) {
  var PreviousBtn = document.getElementById("PreviousBtn");
  PreviousBtn.addEventListener('click', function() {
    // ...
  });

  var NextBtn = document.getElementById("NextBtn");
  NextBtn.addEventListener('click', function() {
    // ...
  });

  var CloseBtn = document.getElementById("CloseBtn");
  CloseBtn.addEventListener('click', function() {
    // ...
  });
}

每次调用OpenModal时,它都会向PreviousBtnNextBtnCloseBtn添加新的事件监听器。因此,单击越多,侦听器调用的函数就越多。

这是一个例子:

var activate = document.getElementById("activate");

activate.addEventListener("click", event => {
  var submit = document.getElementById("submit");
  var result = document.getElementById("result");
  let i = 0;
  result.textContent = "";
  
  submit.addEventListener("click", event => {
    result.textContent += ' ' + i++;
  });
});
body { background: #fafafa }

#result, #hint {
  font-family: fantasy;
  background: #def;
  padding: .5em;
}

#result {
  background: #fde;
  height: 3em;
}
<div id="hint">
  Click on activate, then click submit many times. 
  <br> Click activate again and click submit again many times.
</div>
<div id="result">Result will come here.</div>
<button id="activate">Activate</button>
<button id="submit">Submit</button>
另一答案

因为每次新的侦听器都添加到PreviousBtn,NextBtn和CloseBtn。您需要在OpenModal函数之外定义侦听器,或者为每个定义的事件侦听器使用removeEventListener(没有任何意义)。

一个很好的方法可能是这样的:

// Gallery Lightbox
$(document).ready(function(){
	
  var SlideIndex = 0;
  var Lightbox = document.getElementById("Lightbox");
  var Modal = document.getElementById("ModalContent");
  var Slides = document.getElementsByClassName("ModalSlides");
    
  $('.GalleryImg').on('click', function() { //Attach event handler on each photo
    var GalleryImgs = Array.prototype.slice.call(document.getElementsByClassName('GalleryImg')); //Turns object array to an a proper array
    var ImgIndex = GalleryImgs.indexOf(this); //Position of img clicked
    SlideIndex = ImgIndex; //Passes the index into the modal function
    
    Lightbox.style.display = "block";
    Slides[SlideIndex].style.display = "block";

  });

  
  var PreviousBtn = document.getElementById("PreviousBtn");
  PreviousBtn.addEventListener('click', function() {
    if (SlideIndex > 0) {
      Slides[SlideIndex].style.display = "none";
      SlideIndex --;
      Slides[SlideIndex].style.display = "block";
      console.log("PCurrent = "+SlideIndex);
    } else {
      return;
    }
  });

  var NextBtn = document.getElementById("NextBtn");
  NextBtn.addEventListener('click', function() {
    if (SlideIndex < Slides.length-1) {
      console.log(SlideIndex);
      Slides[SlideIndex].style.display = "none";
      SlideIndex ++;
      Slides[SlideIndex].style.display = "block";
      console.log("NCurrent = "+SlideIndex);
    } else {
      return;
    }
  });

  var CloseBtn = document.getElementById("CloseBtn");
  CloseBtn.addEventListener('click', function() {
    Lightbox.style.display = "none";
    var i = 0;
    while (i < Slides.length) {
      Slides[i].style.display = "none";
      i++
    }
    console.log("Closing Index = "+SlideIndex);
  });

});
/* Gallery */
.Gallery {
  display: block;
  position: relative;
  width: 100%;
  height: auto;
}

.GalleryImg {
  height: auto;
  width: 100%;
  cursor: pointer;
  opacity: 1;
  transition: transform 0.5s;
  transform-origin: 50% 50%;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.Gallery img:hover {
  transform: scale(1.07);
}
/* Lightbox */
#Lightbox {
  display: none;
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  padding-top: 5%;
  z-index: 10;
  background-color: rgba(0,0,0,0.7);
  overflow: auto;
}

#ModalContent {
  position: relative;
  margin: auto;
  width: 90%;
  max-width: 1200px;
}

.ModalSlides {
  display: none;
  position: relative;
  width: 100%;
  height: auto;
}

#CloseBtn {
  color: white;
  position: absolute;
  top: 10px;
  right: 25px;
  font-size: 50px;
  font-weight: bold;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  z-index: 999;
}

#CloseBtn:hover,
#CloseBtn:focus {
  color: #999;
  text-decoration: none;
  cursor: pointer;
}

#NextBtn, #PreviousBtn {
  cursor: pointer;
  position: absolute;
  top: 60%;
  width: auto;
  padding: 20px;
  margin-top: -75px;
  color: white;
  font-weight: bold;
  font-size: 50px;
  transition: 0.5s ease;
  border-radius: 0 3px 3px 0;
  user-select: none;
  -webkit-user-select: none;
}

#NextBtn {
  right: 0;
  border-radius: 3px 0 0 3px;
}

#NextBtn:hover,
#PreviousBtn:hover {
  background-color: rgba(0, 0, 0, 0.8);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="Gallery">
                <div class="row mt-3">
                  <div class="col-4">
                    <img class="GalleryImg" src="http://via.placeholder.com/350x150" alt="">
                  </div>
                  <div class="col-4">
                    <img class="GalleryImg" src="http://via.placeholder.com/380x150" alt="">
                  </div>
                  <div class="col-4">
                    <img class="GalleryImg" src="http://via.placeholder.com/450x150" alt="">
                  </div>
                </div>
                <div class="row mt-3">
                  <div class="col-4">
                    <img class="GalleryImg" src="http://via.placeholder.com/390x150" alt="">
                  </div>
                  <div class="col-4">
                    <img class="GalleryImg" src="http://via.placeholder.com/350x50" alt="">
                  </div>
                  <div class="col-4">
                    <img class="GalleryImg" src="http://via.placeholder.com/350x250" alt="">&

以上是关于JavaScript:多个持久索引变量的主要内容,如果未能解决你的问题,请参考以下文章

持久片段和查看器

Chrome-Devtools代码片段中的多个JS库

如何使用变量创建具有索引和值的 Javascript 对象?

如何创建片段以重复变量编号中的代码行

片段中的Firebase数据不是持久的,会重新下载

如何永久/持久保存 JavaScript 变量?