使用Javascript在For循环中的一个页面上的多个模态

时间:2017-08-12 23:38:34

标签: javascript html for-loop modal-dialog

我试图在一个页面中允许多个模态。 html设置是:

      <div class="grid-item">
        <img id="Img1" src="https://something"/>
      </div>

      <div id="myModal1" class="modal">
          <span class="close">&times;</span>
          <img class="modal-content" id="img01">
          <div id="caption">Final Product: Folding Paduak Timepiece</div>
      </div>

      <div class="grid-item">
        <img id="Img2" src="https://somethingelse"/>
      </div>

      <div id="myModal2" class="modal">
          <span class="close">&times;</span>
          <img class="modal-content" id="img02">
          <div id="caption">Angled shot of unhinged product</div>
      </div>

      <div class="grid-item">
        <img id="Img3" src="https://somethingagain"/>
      </div>

      <div id="myModal3" class="modal">
          <span class="close">&times;</span>
          <img class="modal-content" id="img03">
          <div id="caption">Downwards view of unhinged product</div>
      </div>

我设法通过重复更多代码来实现这一目标。这在下面说明;这工作:

var modal1 = document.getElementById('myModal1');
var modal2 = document.getElementById('myModal2');
var modal3 = document.getElementById('myModal3');

var img1 = document.getElementById('Img1');
var img2 = document.getElementById('Img2');
var img3 = document.getElementById('Img3');

var modalImg1 = document.getElementById("img01");
var modalImg2 = document.getElementById("img02");
var modalImg3 = document.getElementById("img03");

var captionText1 = document.getElementById("caption1");
var captionText2 = document.getElementById("caption2");
var captionText3 = document.getElementById("caption3");

img1.onclick = function(){
    modal[i].style.display = "block";
    modalImg1.src = this.src;
    captionText1.innerHTML = this.alt;
}
img2.onclick = function(){
    modal2.style.display = "block";
    modalImg2.src = this.src;
    captionText2.innerHTML = this.alt;
}
img3.onclick = function(){
    modal3.style.display = "block";
    modalImg3.src = this.src;
    captionText3.innerHTML = this.alt;
}

var span1 = document.getElementsByClassName("close")[0];
var span2 = document.getElementsByClassName("close")[1];
var span3 = document.getElementsByClassName("close")[2];

span1.onclick = function() { 
    modal1.style.display = "none";
}
span2.onclick = function() { 
    modal2.style.display = "none";
}
span3.onclick = function() { 
    modal3.style.display = "none";
}

为了简化这一点,我创建了一个for循环。这在下面说明;这不起作用:

var = modal[];
var = img[];
var = modalImg[];
var = captionText[];
var = span[];

for (var i = 1; i < 10; i++){
    var modal[i] = document.getElementById("myModal"+ i.toString());
    document.write(modal[i]);
    var img[i] = document.getElementById("Img" + i.toString());
    var modalImg[i] = document.getElementById("img0" + i.toString());
    var captionText[i] = document.getElementById("caption");
    img[i].onclick = function(){
        modal[i].style.display = "block";
        modalImg[i].src = this.src;
        captionText[i].innerHTML = this.alt;
    }
    var span[i] = document.getElementsByClassName("close")[(i-1)];
    span[i].onclick = function() { 
    modal[i].style.display = "none";
    }
}

任何帮助将不胜感激!我是JavaScript的新手,我不太清楚问题是什么。

2 个答案:

答案 0 :(得分:0)

Javascript函数会使用它们的上下文,即使它们稍后执行也是如此。在for循环中,您可以定义两个函数(一个用于打开模态,另一个用于关闭)。这些函数中的每一个都在访问循环变量i,因为它是在函数外部定义的。如果i被修改(在循环期间),则该函数在执行时访问新的修改后的值。

(这在javascript中既是一个很大的难度也是一个很大的机会!)

在这种情况下,只需在for循环中定义一个新变量,就可以达到你想要的效果:

for (var i = 1; i < 10; i++){
  var modal[i] = document.getElementById("myModal"+ i.toString());
  document.write(modal[i]);
  var img[i] = document.getElementById("Img" + i.toString());
  var modalImg[i] = document.getElementById("img0" + i.toString());
  var captionText[i] = document.getElementById("caption");
  // before we define any functions, give the current index a new variable
  var currentIndex = i;
  // use the new variable in the functions to be executed later
  img[i].onclick = function(){
    modal[currentIndex].style.display = "block";
    modalImg[currentIndex].src = this.src;
    captionText[currentIndex].innerHTML = this.alt;
  }
  var span[i] = document.getElementsByClassName("close")[(i-1)];
  span[i].onclick = function() { 
    modal[currentIndex].style.display = "none";
  }

}

答案 1 :(得分:0)

根据您提供的完整fiddle,我可以看到您已经在使用jquery进行网格布局。使用jquery,我可以给出一个更简单的解决方案 - 这里是modified fiddle

基本上,您可以向相关图像和模态添加data-index属性,然后使用单个事件侦听器来管理模态打开。相关的javascript是:

/* jquery and data-property method */
$(function() {
  $('body').on('click', '.modal-img', function(event) {
    var $img = $(event.target);
    var index = $img.data('index');
    var $modal = $("#myModal" + index);
    $modal.find('img').attr('src', $img.attr('src'));
    $modal.find('#caption').text($img.attr('alt'));
    $modal.css('display', 'block');
  });

  $('body').on('click', '.modal .close', function(event) {
    var $modal = $(event.target).closest('.modal');
    $modal.css('display', 'none');
  });
});

除了在你的html中添加data-index之外,还可以使用。

如果你想更进一步,可以指点一下。 Jquery可以用来相当容易地执行诸如“查找当前.modal元素之后的img元素”之类的事情,从而无需一起索引。此外,如果您只引用单个模态而不是每个图像一个模式,您的代码仍然可以工作......每次显示模态时,您都会动态更新图像源和标题,因此单个模态将起作用。为了实现这一点,只需从html中删除除一个模态以外的所有模式,并确保在提供的代码中$modal引用它。

祝你好运!