Как создать модальное изображение для нескольких изображений внутри цикла? - PullRequest
2 голосов
/ 27 марта 2019

Я пытаюсь создать модальное (диалоговое окно), которое по умолчанию скрыто для нескольких изображений на странице.Каждый раз, когда вы нажимаете на модал, он будет отображать изображение.Я нашел этот пример в коде w3school, как показано ниже

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {font-family: Arial, Helvetica, sans-serif;}

#myImg {
  border-radius: 5px;
  cursor: pointer;
  transition: 0.3s;
}

#myImg: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;
  width: 80%;
  max-width: 700px;
}

/* Caption of Modal Image */
#caption {
  margin: auto;
  display: block;
  width: 80%;
  max-width: 700px;
  text-align: center;
  color: #ccc;
  padding: 10px 0;
  height: 150px;
}

/* Add Animation */
.modal-content, #caption {  
  -webkit-animation-name: zoom;
  -webkit-animation-duration: 0.6s;
  animation-name: zoom;
  animation-duration: 0.6s;
}

@-webkit-keyframes zoom {
  from {-webkit-transform:scale(0)} 
  to {-webkit-transform:scale(1)}
}

@keyframes zoom {
  from {transform:scale(0)} 
  to {transform:scale(1)}
}

/* 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;
}

/* 100% Image Width on Smaller Screens */
@media only screen and (max-width: 700px){
  .modal-content {
    width: 100%;
  }
}
</style>
</head>
<body>

<h2>Image Modal</h2>
<p>In this example, we use CSS to create a modal (dialog box) that is hidden by default.</p>
<p>We use JavaScript to trigger the modal and to display the current image inside the modal when it is clicked on. Also note that we use the value from the image's "alt" attribute as an image caption text inside the modal.</p>

<img id="myImg" src="img_snow.jpg" alt="Snow" style="width:100%;max-width:300px">

<!-- The Modal -->
<div id="myModal" class="modal">
  <span class="close">&times;</span>
  <img class="modal-content" id="img01">
  <div id="caption"></div>
</div>

<script>
// Get the modal
var modal = document.getElementById('myModal');

// Get the image and insert it inside the modal - use its "alt" text as a caption
var img = document.getElementById('myImg');
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");
img.onclick = function(){
  modal.style.display = "block";
  modalImg.src = this.src;
  captionText.innerHTML = this.alt;
}

// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];

// When the user clicks on <span> (x), close the modal
span.onclick = function() { 
  modal.style.display = "none";
}
</script>

</body>
</html>

, он применим только для одного изображения.Предположим, если я хочу сделать это для нескольких изображений, представленных на странице, как я могу добиться этого?В моем HTML-файле я отображаю список изображений на одной странице, используя цикл for, как показано ниже

  {% for item in itemslist %}
      <img src="{{url_for('image', path=item.thumb)}}" id="img{{loop.index}}" class="img-thumbnail" alt=""width="100" height="100"/>
{% endfor %}

, как я могу сделать модальное изображение для всех изображений. Как в этом image

я нашел этот пример модальное изображение но это не помогло, так как выдает ошибку консоли, может быть, я ошибался.Помогите мне исправить эту проблему.Дайте мне знать, если вам нужно больше спросить

Попытка на основе ответов

{% extends "base.html" %}
{% block content %}

<ul class="list-group">
  {% for item in listitems %}
  <li class="list-group-item d-flex justify-content-between align-items-center">

    <a href="/browse/{{item.href}}" id="item{{loop.index}}">{{item.name}}</a>
    <!--below hyperlink is just a hack for creating a clickable space-->
    <a href="/browse/{{item.href}}" id="blahh{{loop.index}}" style="color:white">{{item.name}}</a>
    {% if item.thumb != "" %}
      <!-- <img src="{{url_for('image', fpath=item.thumb)}}" id="img{{loop.index}}" class="img-thumbnail" alt=""width="300" height="300"/> -->
      <img src="{{url_for('image', fpath=item.thumb)}}" id="img{{loop.index}}" class="clickable" alt=""width="300" height="300"/>
      <div id="myModal" class="modal">
  <span class="close">&times;</span>
  <img class="modal-content" id="img01">
  <div id="caption"></div>
</div>
    {% endif %}   
  </li>
  {% endfor %}
</ul>
<script>
/* JavaScript */

// define variables to hold the 'modal' Elements
var modal, modalImg, captionText, close;

// Event Handler
function imageClicked(e) {
   // set modal Elements on first click
   !modal && (
        modal = document.getElementById("modal"),
        modalImg = document.getElementById("img01"),
        captionText = document.getElementById("caption"),
        // find the 'close' button and add an event listener
        close = document.getElementsByClassName("close")[0],
        close.addEventListener("click", closeModal, !1)
    );

    // the clicked image
    var clickedImage = e.target;

    // set the Elements in the 'modal' box
    modalImg.src = clickedImage.src;
    captionText.innerHTML = clickedImage.title;
    modal.style.display = "block";
}

// Event Handler
function closeModal(e) {
    modal.style.display = "none";
}

// Finally, add an event listener to
// every image with a class .clickable
[].slice.call(
    document.getElementsByClassName("clickable")
).forEach(function(im) {
    im.addEventListener("click", imageClicked, !1);
});
</script>
{% endblock %}

В итоге я получил ошибку консоли как это

Ответы [ 2 ]

0 голосов
/ 27 марта 2019

Этого можно достичь, прикрепив Element.addEventListener ко всем изображениям, которые можно нажимать на странице. Например ...

<!-- HTML -->
<div id="modal">
    <span id="close">&times;</span>
    <img id="modalImg">
    <div id="captionText"></div>
</div>
<div id="clickbox">
    <img class="clickable" src="img1.jpg" title=" Image 1 ">
    <img class="clickable" src="img2.jpg" title=" Image 2 ">
    <img class="clickable" src="img3.jpg" title=" Image 3 ">
    ... etc ...
</div>

...

/* JavaScript */

// dirty selection
function $(a) {
    switch (a.slice(0,1)) {
        case "#":
            return document.getElementById(a.slice(1));
        default:
            return [].slice.call(document.getElementsByClassName(a.slice(1)));
    }
}
//////////////////////////////////////

// define variables to hold the 'modal' Elements
var modal, modalImg, captionText, close;

// Event Handler
function imageClicked(e) {
   // set modal Elements on first click
   !modal && (
        modal = $("#modal"),
        modalImg = $("#modalImg"),
        captionText = $("#captionText"),
        // find the 'close' button and 
        // add an event listener
        close = $("#close"),
        close.addEventListener("click", closeModal, !1)
    );

    // the clicked image
    var clickedImage = e.target;

    // set the Elements in the 'modal' box
    modalImg.src = clickedImage.src;
    captionText.textContent = clickedImage.title;
    modal.style.display = "block";
}

// Event Handler
function closeModal(e) {
    modal.style.display = "none";
}

// Finally, add an event listener to
// every image with a class .clickable
$(".clickable").forEach(function(im) {
    im.addEventListener("click", imageClicked, !1);
});

Установка прослушивателей событий для каждого изображения будет означать, что каждый раз при нажатии img.clickable будет вызываться функция обработки события imageClicked().

В этой функции, если переменная 'modal' не установлена ​​(по первому щелчку), она и все остальные элементы модального блока присваиваются своим собственным переменным. Кроме того, кнопка «Закрыть» получает Element.addEventListener, присоединяющий ее к функции closeModal().

Функция imageClicked() берет информацию из изображения, по которому щелкнули (e.target), который затем используется для заполнения содержимого модального поля, как в примере W3Schools.

Вы найдете рабочий пример @ JSFIDDLE.COM

Надеюсь, что помогло;)

Смотрите также:

0 голосов
/ 27 марта 2019

Я бы пошел с чем-то вроде этого. Вы должны связать событие onclick со всеми вашими изображениями. Что касается вашего кода TWIG, я взял класс img-thumbnail в качестве селектора, чтобы связать событие onclick со всеми вашими изображениями. Поскольку вы не предоставили полностью демонстрирующий пример, я не смог его протестировать (и я немного ленив, TBH). Но так оно и должно работать. Только заменить существующий код. Я почти уверен, что это уже должно сделать эту работу.

// Get the images and bind an onclick event on each to insert it inside the modal
// use its "alt" text as a caption
var images = document.querySelectorAll(".img-thumbnail");
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");
for(let i = 0; i < images.length; i++){
  images[i].onclick = function(){
    modal.style.display = "block";
    modalImg.src = this.src;
    captionText.innerHTML = this.alt;
  }
}

Полный рабочий пример:

// Get the modal
var modal = document.getElementById('myModal');

// Get the images and bind an onclick event on each to insert it inside the modal
// use its "alt" text as a caption
var images = document.querySelectorAll(".img-thumbnail");
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");
for(let i = 0; i < images.length; i++){
  images[i].onclick = function(){
    modal.style.display = "block";
    modalImg.src = this.src;
    captionText.innerHTML = this.alt;
  }
}

// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];

// When the user clicks on <span> (x), close the modal
span.onclick = function() {
  modal.style.display = "none";
} 
 /* Style the Image Used to Trigger the Modal */
.img-thumbnail{
  border-radius: 5px;
  cursor: pointer;
  transition: 0.3s;
}

.img-thumbnail: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;
  width: 80%;
  max-width: 700px;
}

/* Caption of Modal Image (Image Text) - Same Width as the Image */
#caption {
  margin: auto;
  display: block;
  width: 80%;
  max-width: 700px;
  text-align: center;
  color: #ccc;
  padding: 10px 0;
  height: 150px;
}

/* Add Animation - Zoom in the Modal */
.modal-content, #caption {
  animation-name: zoom;
  animation-duration: 0.6s;
}

@keyframes zoom {
  from {transform:scale(0)}
  to {transform:scale(1)}
}

/* 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;
}

/* 100% Image Width on Smaller Screens */
@media only screen and (max-width: 700px){
  .modal-content {
    width: 100%;
  }
} 
 <!-- Trigger the Modal -->
<img id="myImg1" src="//i.stack.imgur.com/bpLjl.png" class="img-thumbnail" alt="Angular" style="width:100%;max-width:50px">
<img id="myImg2" src="https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon.png?v=c78bd457575a" class="img-thumbnail" alt="Stacky" style="width:100%;max-width:50px">

<!-- The Modal -->
<div id="myModal" class="modal">

  <!-- The Close Button -->
  <span class="close">&times;</span>

  <!-- Modal Content (The Image) -->
  <img class="modal-content" id="img01">

  <!-- Modal Caption (Image Text) -->
  <div id="caption"></div>
</div> 

` Обновление: добавлен полный рабочий пример на основе исходного ответа.

...