Javascript несколько циклов для отображения информации мой модальный - PullRequest
0 голосов
/ 28 июня 2018

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

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

Обнаружена проблема - myName [i] .innerHTML, я не могу добраться до переменной i, получаю ошибку (не могу прочитать свойство 'innerHTML' из неопределенного), если я ввожу число вручную, тогда оно печатает имя правильно.

// Get modal
let modal = document.getElementById("myModal");
let i;

// Get image
let img = document.getElementsByClassName("myImg");
let myName = document.getElementsByClassName("myName");
let myDesc = document.getElementsByClassName("myDesc");
let modalImg = document.getElementById("showImg");
let modalName = document.getElementById("imgName");
let modalDesc = document.getElementById("imgDesc");

// Loop through images
for (i = 0; i < img.length; i++) {
    img[i].onclick = function () {
        modal.style.display = "block";
        modalImg.src = this.src;
        modalName.innerHTML = myName[i].innerHTML;
        modalDesc.innerHTML = myDesc[i].innerHTML;
    }
}
 // Images
<div>
    <img class="myImg" src="images/1.png" alt="">
    <h5 class="myName">Image name1</h5>
    <p class="myDesc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, quaerat, aut.</p>
</div>

<div>
    <img class="myImg" src="images/2.png" alt="">
    <h5 class="myName">Image name2</h5>
    <p class="myDesc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, quaerat, aut.</p>
</div>

<div>
    <img class="myImg" src="images/3.png" alt="">
    <h5 class="myName">Image name3</h5>
    <p class="myDesc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium, debitis, provident.</p>
</div>

// Modal
<div id="myModal" class="modal">
    <span class="close">&times;</span>
    <img class="modal-content" id="showImg">
    <div id="imgName"></div>
    <div id="imgDesc"></div>
</div>

Ответы [ 5 ]

0 голосов
/ 28 июня 2018
Thanks for your effort guys, I fixed it with adding id to each image, I know it's hard coded... But oh well, I will get better.



 // Loop through images
       for(i=0; i < img.length; i++){
          img[i].onclick = function(){
            modal.style.display = "block";
            modalImg.src = this.src;
            modalName.innerHTML = myName[this.id-1].innerHTML;
            modalDesc.innerHTML = myDesc[this.id-1].innerHTML;
          }
        }



          <div>
            <img class="myImg" src="images/2.png" alt="" id="1">
            <h5 class="myName">Image name1</h5>
            <p class="myDesc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, quaerat, aut.</p>
          </div>
          <div>
            <img class="myImg" src="images/3.png" alt="" id="2">
            <h5 class="myName">Image name2</h5>
            <p class="myDesc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, quaerat, aut.</p>
          </div>
          <div>
            <img class="myImg" src="images/4.png" alt="" id="3">
            <h5 class="myName">Image name3</h5>
            <p class="myDesc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium, debitis, provident.</p>
          </div>
0 голосов
/ 28 июня 2018

Проблема заключается в вашем слушателе событий onClick. Вы используете переменную i в вашем слушателе. К тому времени, когда кто-то нажимает на изображение, цикл завершается и значение i становится равным 3 и не изменяется, а поскольку в ваших myName и myDesc есть только 3 элемента, оно выдает ошибку и останавливается выполнение.

Вы можете использовать следующий код:

  let modal = document.getElementById("myModal");
  let i;
  let j;
  let k;

  // Get image
  let img = document.getElementsByClassName("myImg");
  let myName = document.getElementsByClassName("myName");
  let myDesc = document.getElementsByClassName("myDesc");
  let modalImg = document.getElementById("showImg");
  let modalName = document.getElementById("imgName");
  let modalDesc = document.getElementById("imgDesc");

  // Loop through images
  for (i = 0; i < img.length; i++) {
    img[i].onclick = function () {
      modal.style.display = "block";
      modalImg.src = this.src;
      modalName.innerHTML = this.parentElement.getElementsByClassName('myName')[0].innerHTML;
      modalDesc.innerHTML = this.parentElement.getElementsByClassName('myDesc')[0].innerHTML;
    }
  }
// Images
<div>
  <img class="myImg" src="images/1.png" alt="">
  <h5 class="myName">Image name1</h5>
  <p class="myDesc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, quaerat, aut.</p>
</div>

<div>
  <img class="myImg" src="images/2.png" alt="">
  <h5 class="myName">Image name2</h5>
  <p class="myDesc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, quaerat, aut.</p>
</div>

<div>
  <img class="myImg" src="images/3.png" alt="">
  <h5 class="myName">Image name3</h5>
  <p class="myDesc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium, debitis, provident.</p>
</div>

// Modal
<div id="myModal" class="modal">
  <span class="close">&times;</span>
  <img class="modal-content" id="showImg">
  <div id="imgName"></div>
  <div id="imgDesc"></div>
</div>
Ключевое слово

this всегда будет указывать на изображение, по которому щелкнули, и, таким образом, использование this.parentElement.getElementsByClassName('myName')[0] даст вам нужный элемент.

0 голосов
/ 28 июня 2018

Я добавил изображения местозаполнителя в вашем примере, и он отлично работает.

<div>
    <img class="myImg" src="http://via.placeholder.com/350x50" alt="">
    <h5 class="myName">Image name1</h5>
    <p class="myDesc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, quaerat, aut.</p>
</div>

<div>
    <img class="myImg" src="http://via.placeholder.com/350x100" alt="">
    <h5 class="myName">Image name2</h5>
    <p class="myDesc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, quaerat, aut.</p>
</div>


<div>
    <img class="myImg" src="http://via.placeholder.com/350x150" alt="">
    <h5 class="myName">Image name3</h5>
    <p class="myDesc">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium, debitis, provident.</p>
</div>

<script>
let img = document.getElementsByClassName("myImg");
let myName = document.getElementsByClassName("myName");
let myDesc = document.getElementsByClassName("myDesc");
let modalImg = document.getElementById("showImg");
let modalName = document.getElementById("imgName");
let modalDesc = document.getElementById("imgDesc");

for(i=0; i < img.length; i++) {
  img[i].onclick = function() {
    modal.style.display = "block";
    modalImg.src = this.src;
    modalName.innerHTML = myName[i].innerHTML;
    modalDesc.innerHTML = myDesc[i].innerHTML;
  }
}
</script>

Проверьте Скрипка

Изображение, на которое вы нажимаете, расширяется в нижней части. Как в примере нет Bootstrap или другой модальной поддержки присутствовал, но код должен работать. Дайте мне знать, если потребуется какая-либо помощь.

0 голосов
/ 28 июня 2018

Вы определяете переменные цикла вне цикла. Эти переменные находятся внутри закрытия обработчика кликов. Происходит следующее:

  • Вы перебираете все изображения и добавляете обработчик кликов
  • Каждый обработчик кликов имеет ссылку на одни и те же переменные цикла
  • Цикл завершается, все переменные цикла находятся на максимуме
  • Когда происходит щелчок, обработчик щелчка получает доступ к переменным максимизированного цикла, поэтому всегда выбирается последняя запись

Чтобы этого не происходило, вы можете создавать различные функции со своими индексами:

function createaHandler(src, j, k) {
    return function (src, j, k) {
        modal.style.display = "block";
        modalImg.src = src;
        modalName.innerHTML = myName[j].innerHTML;
        modalDesc.innerHTML = myDesc[k].innerHTML;
    }
}

for (i = 0, j = 0, k = 0; i < img.length, j < myName.length, k < myDesc.length; i++ , j++ , k++) {
    img[i].onclick = createHandler(img[i].src, j, k);
}

Более простой метод - определить соответствующие переменные в каждом новом цикле, чтобы они сбрасывались и содержали правильные значения:

for (i = 0; i < img.length; i++) {
    let src = img[i].src;
    let nameHTML = myName[i].innerHTML;
    let descHTML = myDesc[i].innerHTML;
    img[i].onclick = function () {
        modal.style.display = "block";
        modalImg.src = src;
        modalName.innerHTML = nameHTML;
        modalDesc.innerHTML = descHTML;
    }
}
0 голосов
/ 28 июня 2018

Я думаю, что лучше использовать атрибуты данных для хранения значений, в любом случае попробуйте это.

let wrapper = document.querySelector('.wrapper div');

wrapper.addEventListener('click', function() {

  let img = this.querySelector('.myImg');
  console.log(img);
});

полная ссылка https://jsfiddle.net/gcvex46o/30/

...