JavaScript:多个持久索引变量

问题描述 投票:3回答:2

我是编程世界的新手,在使用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);
    });

  };

});
javascript html css variables scope
2个回答
2
投票

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

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>

在片段中,如果您激活然后提交五次,并重复这样做四次,您会得到:

0 1 2 3 4 5 0 6 1 7 2 8 3 9 4 10 5 0 11 6 1 12 7 2 13 8 3 14 9 4 15 10 5 0 16 11 6 1 17 12 7 2 18 13 8 3 19 14 9 4

因为每次点击activate时,都会添加一个新的i

所以你应该拥有的是:

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() {
  // ...
});

function OpenModal(n) {
  // ...  
}

这样,监听器只添加一次。


2
投票

因为每次新的侦听器都添加到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="">
                  </div>
                </div>
              </div>


              <div id="Lightbox">
                <span id="CloseBtn">&times;</span>

                <div id="ModalContent">
                  <img class="ModalSlides" src="http://via.placeholder.com/350x150" alt="">
                  <img class="ModalSlides" src="http://via.placeholder.com/380x150" alt="">
                  <img class="ModalSlides" src="http://via.placeholder.com/450x150" alt="">
                  <img class="ModalSlides" src="http://via.placeholder.com/390x150" alt="">
                  <img class="ModalSlides" src="http://via.placeholder.com/350x50" alt="">
                  <img class="ModalSlides" src="http://via.placeholder.com/350x250" alt="">
                  <a id="PreviousBtn">&#10094;</a>
                  <a id="NextBtn">&#10095;</a>
                </div>
              </div>

通过这种方式,我们只定义了一次事件监听器。 SlideIndexLightboxModalSlides变量在开头定义。

© www.soinside.com 2019 - 2024. All rights reserved.