Как открыть изображение по клику

У меня есть модальное окно для первой карточки, но когда я хочу добавить это окно ко второй картинке, оно не работает. Как сделать чтобы изображения открывались на всех картах? ㅤㅤ

// 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";
}
.product-card-container {
  display: flex;
  justify-content: space-around;
  flex-wrap: wrap;
}

.wrapper_div {
  /* Кнопка купить выравнивание */
  display: flex;
  flex-direction: column;
  align-items: center;
}

.nft {
  user-select: none;
  width: 300px;
  margin: 2rem;
  border: 1px solid #ffffff22;
  background-color: #282c34;
  background: linear-gradient(0deg, rgba(40, 44, 52, 1) 0%, rgba(17, 0, 32, .5) 100%);
  box-shadow: 0 7px 20px 5px #00000088;
  border-radius: .7rem;
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
  overflow: hidden;
  transition: .5s all;
  hr {
    width: 100%;
    border: none;
    border-bottom: 1px solid #88888855;
    margin-top: 0;
  }
  ins {
    text-decoration: none;
  }
  .main {
    width: 90%;
    padding: 1rem;
    color: #c572e6;
    display: flex;
    flex-direction: column;
    .tokenImage {
      border-radius: .5rem;
      max-width: 100%;
      height: 250px;
      object-fit: cover;
    }
    .description {
      min-height: 100px;
      max-height: 100px;
      margin: .5rem 0;
      color: #a89ec9;
    }
    .tokenInfo {
      display: flex;
      justify-content: space-between;
      align-items: center;
      .price {
        display: flex;
        align-items: center;
        color: #ee83e5;
        font-weight: 700;
        ins {
          margin-left: -.3rem;
          margin-right: .5rem;
        }
      }
      .duration {
        display: flex;
        align-items: center;
        color: #a89ec9;
        margin-right: .2rem;
        ins {
          margin: .5rem;
          margin-bottom: .4rem;
        }
      }
    }
    .creator {
      display: flex;
      align-items: center;
      margin-top: .2rem;
      margin-bottom: -.3rem;
      ins {
        color: #a89ec9;
        text-decoration: none;
      }
      .wrapper {
        display: flex;
        align-items: center;
        border: 1px solid #ffffff22;
        padding: .3rem;
        margin: 0;
        margin-right: .5rem;
        border-radius: 100%;
        box-shadow: inset 0 0 0 4px #000000aa;
        img {
          border-radius: 100%;
          border: 1px solid #ffffff22;
          width: 2rem;
          height: 2rem;
          object-fit: cover;
          margin: 0;
        }
      }
    }
  }
   ::before {
    position: fixed;
    content: "";
    box-shadow: 0 0 100px 40px #ffffff08;
    top: -10%;
    left: -100%;
    transform: rotate(-45deg);
    height: 60rem;
    transition: .7s all;
  }
  &:hover {
    border: 1px solid #ffffff44;
    box-shadow: 0 7px 50px 10px #000000aa;
    transform: scale(1.015);
    filter: brightness(1.3);
     ::before {
      filter: brightness(.5);
      top: -100%;
      left: 200%;
    }
  }
}

.bg {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  h1 {
    font-size: 20rem;
    filter: opacity(0.5);
  }
}

#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 (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%;
  }
}
<div class = "product-card-container">
  <div class = "wrapper_div">
    <div class = "nft">
      <div class='main'>
        <img class='tokenImage' id = "myImg" src = "http://kartinkof.club/uploads/posts/2022-04/1649561882_6-kartinkof-club-p-ugarnie-kartinki-shrek-7.jpg" alt = "Snow" style = "width: 100%; max-width: 300px">
        <h2>XXX</h2>
        <p class='description'>XXX</p>
        <div class='tokenInfo'>
          <div class = "price">
            <ins>◘</ins>
            <p>499 Руб</p>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class = "wrapper_div">
    <div class = "nft">
      <div class='main'>
        <img class='tokenImage' src = "http://kartinkof.club/uploads/posts/2022-04/1649561882_6-kartinkof-club-p-ugarnie-kartinki-shrek-7.jpg" alt = "NFT" />
        <h2>Заяц</h2>
        <p class='description'>XXX</p>
        <div class='tokenInfo'>
          <div class = "price">
            <ins>◘</ins>
            <p>179 Руб</p>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class = "wrapper_div">
    <div class = "nft">
      <div class='main'>
        <img class='tokenImage' src = "http://kartinkof.club/uploads/posts/2022-04/1649561882_6-kartinkof-club-p-ugarnie-kartinki-shrek-7.jpg" alt = "NFT" />
        <h2>XXX</h2>
        <p class='description'>XXX</p>
        <div class='tokenInfo'>
          <div class = "price">
            <ins>◘</ins>
            <p>179 Руб</p>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class = "wrapper_div">
    <div class = "nft">
      <div class='main'>
        <img class='tokenImage' src = "http://kartinkof.club/uploads/posts/2022-04/1649561882_6-kartinkof-club-p-ugarnie-kartinki-shrek-7.jpg" alt = "NFT" />
        <h2>XXX</h2>
        <p class='description'>XXXㅤㅤ</p>
        <div class='tokenInfo'>
          <div class = "price">
            <ins>◘</ins>
            <p>179 Руб</p>
          </div>
        </div>
      </div>
    </div>
    <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>
  </div>

Вы добавили обработчик onclick только к первому изображению. Вам нужно добавить обработчик ко всем изображениям. Или один обработчик корневого элемента, если вы так предпочитаете.

001 21.05.2024 13:49

Если я его добавлю, изображение вообще перестанет открываться

SoundestMage 21.05.2024 13:56
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам нужно сделать что-то вроде этого:

Вместо того, чтобы брать один элемент img. Возьмите в качестве массива все изображения в соответствии с их именем класса:

let imgs= document.querySelectorAll(".tokenImage");

Затем измените функцию с функции, которая применяется только к одному элементу, на функцию, которая применяется ко всему массиву:

imgs.forEach(img => {
    img.onclick = (event) => {
        modal.style.display = "block";
        modalImg.src = event.target.src;
        captionText.innerHTML = event.target.alt;
    };
});

И я рекомендую вам добавить в css:

 .tokenImage:hover{
         cursor: pointer;
       }

Я запустил код, и у меня он работал нормально. Если у вас возникнут проблемы, вы можете спросить...

Ой, извини @community wiki, пока я дорабатываю свой ответ, я обнаруживаю, что ты сделал примерно то же самое, что и я.

Agota Kristof 21.05.2024 14:24

Один из вариантов — добавить обработчик событий к каждому изображению. В настоящее время вы добавляете обработчик только к первому изображению.

Изменять:

var img = document.getElementById("myImg");
img.onclick = function() {
  modal.style.display = "block";
  modalImg.src = this.src;
  captionText.innerHTML = this.alt;
}

К

document.querySelectorAll(".tokenImage").forEach(img => {
    img.onclick = (event) => {
        modal.style.display = "block";
        modalImg.src = event.target.src;
        captionText.innerHTML = event.target.alt;
    };
});

Это добавит обработчик «щелчка» к каждому элементу, имеющему класс tokenImage.

Другие вопросы по теме

Похожие вопросы

Как изолировать вызов API для одного компонента в этом приложении Angular 16?
Ожидаемый тип берется из свойства, которое объявлено здесь для типа IntrinsicAttributes & --prop
Нарисуйте изображение внутри холста HTML, используя определенную ширину/высоту
Создайте несколько магазинов в IndexedDB и получите уведомление, когда все они станут доступны
Изменение всплывающих подсказок узлов в хайчартере Санки
Как преобразовать строку значения атрибута элемента HTML в функцию, подобную onclick
Как найти ключи значений в json с помощью forEach и изменить значения соответствующих ключей с помощью машинописного текста vue js?
Что означает «следующие дополнительные имена» в спецификации ECMA-262?
Angular getLocaleFirstDayOfWeek('en-FR') возвращает 0 (воскресенье) в качестве начального дня недели, тогда как он возвращает 1 (понедельник) для en-NL
Ошибка при попытке упаковать электронное приложение