JavaScript:多个持久索引变量

标签 javascript html css variables scope

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

因此,缩略图调用一个模式,其中包含通过索引作为参数传递的适当图像。我使用了一些 JQuery 来在所有缩略图上附加处理程序而不循环。

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

如果这是一个非常明显的错误,我们深表歉意。我并没有真正在这个论坛上发帖,而是尝试自己解决它,但是在大约 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 时,它都会向 PreviousBtnNextBtn 添加新的事件监听器>关闭按钮。所以点击越多,监听器调用的函数就越多。

这是一个例子:

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

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

关于JavaScript:多个持久索引变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49021149/

相关文章:

javascript - Reveal.js 不支持 AJAX

javascript - :gt(0) vs :not(:first) vs . 切片(1)

javascript - 为什么在我关闭我的 android 应用程序后 javascript 继续?

javascript - 如何使用 jquery 在内部查找具有指定文本的按钮?

html - 不能使用十六进制代码为 <a> 标记着色?

html - 试图使图像网格居中并保持在左侧

javascript - 在 Javascript 中获取和设置 map 中的值

javascript - 仅更改折叠容器的图像 src

javascript - CSS动画汉堡包图标并删除滚动类?

css - Bootstrap 4 - 水平对齐内联列表