开发者问题收集

如何使模态框适用于网站图库中的多幅图像?

2022-05-18
69

我已经学会了如何在单击缩略图时在模式中打开图像,但我遇到的问题是让它适用于页面上的多个缩略图。这是一个示例,只有 3 张图片,但最终我会有超过 3 张。我收到一个控制台错误 TypeError:null 不是对象(评估“document.getElementById(img)”)我希望能够有一个图像库,您单击其中任何一个,模式就会弹出,您单击 x 或背景,模式就会关闭。我可以对单个图像执行此操作,也可以对多个图像执行此操作,每个图像都有一个单独的脚本,但只有最后一个可以关闭。我正在尝试找到某种方法对数组执行此操作,因此它适用于页面上的所有图像。

<!DOCTYPE html>
<html>
    
    <head>
        <style>

/* Style the Image Used to Trigger the Modal */
#myImg_001, #myImg_002, #myImg_003 {
  border-radius: 5px;
  cursor: pointer;
  transition: 0.3s;
}
#myImg_001:hover, #myImg_002:hover, #myImg_003:hover {opacity: 0.7;}
            
            /* The Modal (background) */
.modal {
  display: none; /* Hidden by default */
  position: fixed; /* Stay in place */
  z-index: 1; /* Sit on top */
  padding-top: 100px; /* Location of the box */
  left: 0;
  top: 0;
  width: 100%; /* Full width */
  height: 100%; /* Full height */
  overflow: auto; /* Enable scroll if needed */
  background-color: rgb(0,0,0); /* Fallback color */
  background-color: rgba(0,0,0,0.9); /* Black w/ opacity */
}

/* Modal Content (Image) */
.modal-content {
  margin: auto;
  display: block;
  height: auto;
  width: 80%;
  max-width: 700px;
}
            
/* The Close Button */               
#close_001, #close_002, #close_003 {
  position: absolute;
  top: 15px;
  right: 35px;
  color: #f1f1f1;
  font-size: 40px;
  font-weight: bold;
  transition: 0.3s;
}

#close_001:hover, #close_002:hover, #close_003:hover,
#close_001:focus, #close_002:focus, #close_003:focus {
  color: #bbb;
  text-decoration: none;
  cursor: pointer;
}

#caption_001, #caption_002, #caption_003 {
  margin: auto;
  display: block;
  color: white;
  padding: 10px 0;
  height: 150px;
  width: 80%;
  max-width: 700px;
}
            
        </style>
    </head>
    
    <body>
        
        <img id="myImg_001" src="https://www.w3schools.com/w3images/ocean.jpg" alt="Image 1">
        <img id="myImg_002" src="https://www.w3schools.com/w3images/rocks.jpg" alt="Image 2">
        <img id="myImg_003" src="https://www.w3schools.com/w3images/underwater.jpg" alt="Image 3">
        
        <div id="myModal_001" class="modal">
            <span id="close_001">&times;</span>
            <img class="modal-content" id="img_001">
            <div id="caption_001" ></div>
        </div>
        
        <div id="myModal_002" class="modal">
            <span id="close_002">&times;</span>
            <img class="modal-content" id="img_002">
            <div id="caption_002" ></div>
        </div>
        <div id="myModal_003" class="modal">
            <span id="close_003">&times;</span>
            <img class="modal-content" id="img_003">
        <div id="caption_003" ></div>
        </div>
      
<script>
    
var myImgArray = [ 'myImg_001', 'myImg_002', 'myImg_003' ];
                  
var myModalArray = [ 'myModal_001', 'myModal_002', 'myModal_003' ];
    
var imgIdArray = [ 'img_001', 'img_002', 'img_003' ];
    
var captionArray = [ 'caption_001', 'caption_002', 'caption_003' ];
    
var closeArray = [ 'close_001', 'close_002', 'close_003' ];

function modalFunction(index, value) { 
        // Get the modal
        var modal = myModalArray[i];
        // Get the image and insert it inside the modal - use its "alt" text as a caption
        var img = myImgArray[i];
        var modalImg = imgIdArray[i];
        var captionText = captionArray[i];
        var close = closeArray[i];
        document.getElementById(img).onclick = function() {
        document.getElementById(modal).style.display = "block";
        document.getElementById(modalImg).src = this.src;
        document.getElementById(captionText).innerHTML = this.alt;
    }
document.getElementById(close).onclick = function() { document.getElementById(modal).style.display = "none"; }
window.onclick = function(event) { if (event.target == document.getElementById(modal)) { document.getElementById(modal).style.display = "none"; } }
    }    
    
myModalArray.forEach(modalFunction);    
        

</script>
    </body>
</html>
2个回答

您不需要存储那么多变量或为每个图像创建单独的模态框。

const images = document.querySelectorAll(".body__image");
const closeButtons = document.querySelectorAll(".close");

const toggleModal = (image) => {
  const modal = document.querySelector(`#modal`);
  modal.classList.toggle("hidden");

  if (image) {
    const modalImage = modal.querySelector("img");
    modalImage.src = image.src;
    const modalCaption = modal.querySelector("#caption");
    modalCaption.innerHTML = image.alt;
  }
};

images.forEach((image) => {
  image.addEventListener("click", (event) => {
    toggleModal(image);
  });
});

closeButtons.forEach((closeButton) => {
  closeButton.addEventListener("click", (event) => {
    toggleModal();
  });
});
/* Style the Image Used to Trigger the Modal */
.body__image {
  max-width: 400px;
  border-radius: 5px;
  cursor: pointer;
  transition: 0.3s;
}
.body__image:hover {
  opacity: 0.7;
}

/* The Modal (background) */
.modal {
  display: block; /* Hidden by default */
  position: fixed; /* Stay in place */
  z-index: 1; /* Sit on top */
  padding-top: 100px; /* Location of the box */
  left: 0;
  top: 0;
  width: 100%; /* Full width */
  height: 100%; /* Full height */
  overflow: auto; /* Enable scroll if needed */
  background-color: rgb(0, 0, 0); /* Fallback color */
  background-color: rgba(0, 0, 0, 0.9); /* Black w/ opacity */
}

/* Modal Content (Image) */
.modal-content {
  margin: auto;
  display: block;
  height: auto;
  width: 80%;
  max-width: 700px;
}

/* The Close Button */
.close {
  position: absolute;
  top: 15px;
  right: 35px;
  color: #f1f1f1;
  font-size: 40px;
  font-weight: bold;
  transition: 0.3s;
}

.close:hover,
.close:focus {
  color: #bbb;
  text-decoration: none;
  cursor: pointer;
}

.caption {
  margin: auto;
  display: block;
  color: white;
  padding: 10px 0;
  height: 150px;
  width: 80%;
  max-width: 700px;
}

.hidden {
  display: none;
}
<!DOCTYPE html>
<html>
  <head>
    <title>Modal Example</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <img
      class="body__image"
      id="myImg_001"
      src="https://www.w3schools.com/w3images/ocean.jpg"
      alt="Image 1"
    />
    <img
      class="body__image"
      id="myImg_002"
      src="https://www.w3schools.com/w3images/rocks.jpg"
      alt="Image 2"
    />
    <img
      class="body__image"
      id="myImg_003"
      src="https://www.w3schools.com/w3images/underwater.jpg"
      alt="Image 3"
    />

    <div id="modal" class="modal hidden">
      <span class="close">&times;</span>
      <img class="modal-content" />
      <div id="caption"></div>
    </div>

    <script src="src/index.js"></script>
  </body>
</html>
David Kerr
2022-05-19

我现在已经让它工作了。我的主要问题是对 forEach 的使用不正确,在我切换到传统的 for 循环后,它现在可以正常工作了。

<!DOCTYPE html>
<html>
    
    <head>
        <style>

/* Style the Image Used to Trigger the Modal */
#myImg_001, #myImg_002, #myImg_003 {
  border-radius: 5px;
  cursor: pointer;
  transition: 0.3s;
}
#myImg_001:hover, #myImg_002:hover, #myImg_003:hover {opacity: 0.7;}
            
            /* The Modal (background) */
.modal {
  display: none; /* Hidden by default */
  position: fixed; /* Stay in place */
  z-index: 1; /* Sit on top */
  padding-top: 100px; /* Location of the box */
  left: 0;
  top: 0;
  width: 100%; /* Full width */
  height: 100%; /* Full height */
  overflow: auto; /* Enable scroll if needed */
  background-color: rgb(0,0,0); /* Fallback color */
  background-color: rgba(0,0,0,0.9); /* Black w/ opacity */
}

/* Modal Content (Image) */
.modal-content {
  margin: auto;
  display: block;
  height: auto;
  width: 80%;
  max-width: 700px;
}
            
#close_001, #close_002, #close_003 {
  position: absolute;
  top: 15px;
  right: 35px;
  color: #f1f1f1;
  font-size: 40px;
  font-weight: bold;
  transition: 0.3s;
}

#close_001:hover, #close_002:hover, #close_003:hover,
#close_001:focus, #close_002:focus, #close_003:focus {
  color: #bbb;
  text-decoration: none;
  cursor: pointer;
}

#caption_001, #caption_002, #caption_003 {
  margin: auto;
  display: block;
  color: white;
  padding: 10px 0;
  height: 150px;
  width: 80%;
  max-width: 700px;
}
            
        </style>
    </head>
    
    <body>
        
        <img id="myImg_001" src="https://www.w3schools.com/w3images/ocean.jpg" alt="Image 1">
        <img id="myImg_002" src="https://www.w3schools.com/w3images/rocks.jpg" alt="Image 2">
        <img id="myImg_003" src="https://www.w3schools.com/w3images/underwater.jpg" alt="Image 3">
        
        <div id="myModal_001" class="modal">
            <span id="close_001">&times;</span>
            <img class="modal-content" id="img_001">
            <div id="caption_001" ></div>
        </div>
        
        <div id="myModal_002" class="modal">
            <span id="close_002">&times;</span>
            <img class="modal-content" id="img_002">
            <div id="caption_002" ></div>
        </div>
        <div id="myModal_003" class="modal">
            <span id="close_003">&times;</span>
            <img class="modal-content" id="img_003">
        <div id="caption_003" ></div>
        </div>
      
<script>
    
var myImgArray = [ 'myImg_001', 'myImg_002', 'myImg_003' ];
                  
var myModalArray = [ 'myModal_001', 'myModal_002', 'myModal_003' ];
    
var imgIdArray = [ 'img_001', 'img_002', 'img_003' ];
    
var captionArray = [ 'caption_001', 'caption_002', 'caption_003' ];
    
var closeArray = [ 'close_001', 'close_002', 'close_003' ];

for (i = 0; i < 3; i++) { 
        var modal = myModalArray[i];
        var img = myImgArray[i];
        var modalImg = imgIdArray[i];
        var captionText = captionArray[i];
        var close = closeArray[i];
        document.getElementById(img).onclick = function() {
        document.getElementById(modal).style.display = "block";
        document.getElementById(modalImg).src = this.src;
        document.getElementById(captionText).innerHTML = this.alt;
    }
document.getElementById(close).onclick = function() { document.getElementById(modal).style.display = "none"; }
window.onclick = function(event) { if (event.target == document.getElementById(modal)) { document.getElementById(modal).style.display = "none"; } }
    }    
    
</script>
    </body>
</html>
synthetick
2022-05-19