2015-12-08 2 views
0

Я пытаюсь создать галерею.innerHTML в массиве

Мне удалось выполнить все шаги, кроме последнего, при нажатии на миниатюру изменится текст в абзаце на другой текст, который я помещаю в массив.

Пока я внутри цикла for, я хочу, чтобы текст индекса 2 показывался, когда я нажимаю образ индекса 2. Я, кажется, следовал правильному синтаксису, но все же в параграфе отображается «undefined " в результате. Однако, когда я выбираю индекс, как и любое изображение, которое я нажимаю, я хочу показать текст индекса 3, он работает.

Вот мой упрощенный код, который должен позволять мне показывать текст при нажатии на абзац. Было бы здорово, если бы вы, ребята, не использовали jQuery. Спасибо вам всем!

<!DOCTYPE html> 
<html> 
<body> 

<p class="demo">1</p> 
<p class="demo">2</p> 
<p class="demo">3</p> 

    <script> 
     var cars = ["Saab", "Volvo", "BMW"]; 
     var para = document.getElementsByClassName("demo"); 
     for (k=0;k<cars.length;k++){ 
      para[k].onclick=function(){ 
      this.innerHTML = cars[k]; 
      } 
     } 
    </script> 

</body> 
</html> 
+0

Проблема, вероятно, в том, что индекс 'k' не сохраняется между циклами в вашем цикле' for'. Вам нужно использовать закрытие. – Matthew

ответ

3

Используйте закрытия:

<script> 
    var cars = ["Saab", "Volvo", "BMW"]; 
    var para = document.getElementsByClassName("demo"); 
    for (var k = 0; k < cars.length; k++) { 
    (function (k) { 
     para[k].onclick = function() { 
     this.innerHTML = cars[k]; 
     } 
    }(k)); 
    } 
</script> 

Fiddle: http://jsbin.com/zezuhitige

Причина:

значение всегда будет последнее значение цикла. Таким образом, вы всегда будете получать k = 3 при щелчке, значение k выполняется во время клика, которое равно 3. Закрытие предотвращает это, выполняя правильное значение, когда оно назначено.

4

Это проблема с областью обзора javascript. Ваша переменная k, обратите внимание, как вы увеличиваете ее каждый раз. Когда onclick вызывается событием click, k будет иметь 3 как его значение независимо от того, на какое изображение вы нажали.

Вы можете попробовать этот метод обхода (обратите внимание, я вымыл свой код немного)

<!DOCTYPE html> 
 
<html> 
 
<body> 
 

 
<p class="demo">1</p> 
 
<p class="demo">2</p> 
 
<p class="demo">3</p> 
 

 
    <script> 
 
    var cars = ["Saab", "Volvo", "BMW"]; 
 
    var para = document.getElementsByClassName("demo"); 
 

 
    for (k = 0; k < cars.length; k++) { 
 
     (function (index) { 
 
     para[index].onclick = function() { 
 
      this.innerHTML = cars[index]; 
 
     } 
 
     }(k)); 
 
    } 
 
</script> 
 

 
</body> 
 
</html>

В этом случае отдельная копия сделана из к, для каждого значения она принимает , эта копия доступна внутри функции как «индекс».

Для получения более подробной информации о конкретной проблеме, обратитесь к этому сообщению: JavaScript closure inside loops – simple practical example

+0

Отлично! Спасибо. вот что я ищу! Я попытаюсь расшифровать этот код, хотя я новичок, и я не совсем понимаю ту часть, где вы помещаете функцию между круглыми скобками. – Chihab

+0

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

0

Более гибкий способ сделать это было бы что-то вроде этого:

<div id="container"> 
    <p class="demo" data-car="Saab">1</p> 
    <p class="demo" data-car="Volvo">2</p> 
    <p class="demo" data-car="BMW">3</p> 
</div> 

JS:

document.getElementById('container').onclick = function(e) { 
    e = e || window.event; 
    var target = e.srcElement || e.target; 
    while(target != this && !target.className.match(/\bdemo\b/)) { 
     target = target.parentNode; 
    } 
    if(target != this) { 
     // target is now one of the .demo elements 
     target.innerHTML = target.getAttribute("data-car"); 
    } 
}; 

Это ставит данные в себя с элементом, на который он ссылается, и придает только один прослушиватель событий, а не один за автомобиль - в больших приложениях, тем меньше обработчики событий у вас есть, тем лучше!

0

Посмотрите в JS закрытия и попробуйте следующее:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

document.addEventListener("DOMContentLoaded", function(event) { 
 
     var cars = ["Saab", "Volvo", "BMW"]; 
 
     var para = document.getElementsByClassName("demo"); 
 
     for (k=0;k<cars.length;k++){ 
 
      var clojureCar = cars[k]; 
 
      
 
      para[k].onclick=function(){ 
 
      
 
      this.innerHTML = clojureCar; 
 
      } 
 
     } 
 
});
<!DOCTYPE html> 
 
<html> 
 
<body> 
 

 
<p class="demo">1</p> 
 
<p class="demo">2</p> 
 
<p class="demo">3</p> 
 

 
    <script> 
 
     var cars = ["Saab", "Volvo", "BMW"]; 
 
     var para = document.getElementsByClassName("demo"); 
 
     for (k=0;k<cars.length;k++){ 
 
      para[k].onclick=function(){ 
 
      this.innerHTML = cars[k]; 
 
      } 
 
     } 
 
    </script> 
 

 
</body> 
 
</html>

0

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

var cars = ["Saab", "Volvo", "BMW"]; 
var para = document.getElementsByClassName("demo"); 
for (k=0;k<cars.length;k++){ 
    var div = para[k]; 
    (function (i) { 
    div.addEventListener('click', function() { this.innerHTML = cars[i]; }); 
    })(k); 
} 
Смежные вопросы