0

Есть массив объявлений, к каждому из которых генерируется метка на карте и карточка к ней. При клике на метку, должна отобразиться соответствующая ей карточка. Следующий код срабатывает как надо:

 adsList.forEach(item => {
                var pin = renderPin(item);
                var ad = window.card.renderAd(item);
                pin.addEventListener('click', function (evtClick) {                  
                    window.pin.openedPin.classList.add("map__pin--active");
                    ad.classList.remove("hidden");
                })
            });

Но чтобы ограничить число меток на карте, я хочу воспользоваться обычным циклом for и получается следующее:

 for(var i = 0; i < PIN_NUMBER; i++){
                var pin = renderPin(adsList[i]);
                var ad = window.card.renderAd(adsList[i]);
                pin.addEventListener('click', function (evtClick) {                  
                    window.pin.openedPin.classList.add("map__pin--active");
                    ad.classList.remove("hidden");
                })
            });

В этом случае при клике на любую метку отображается та карточка, которая была последней в цикле. Может быть, кто-нибудь может объяснить с чем связано такое поведение?

zinYen
  • 15
  • Пробуйте заменить var на let ) – OPTIMUS PRIME Aug 20 '19 at 17:25
  • @opt Спасибо, сработало! А не могли бы, пожалуйста, объяснить, почему использование var все поломало? – zinYen Aug 20 '19 at 17:32

2 Answers2

0

Здесь не важно, какой код, важно поведение var в цикле, поэтому примеры будут с другим кодом. Допустим, навешиваем событие на кнопки, а при клике - они должны что-то делать с числом i:

var bubu = document.querySelectorAll('.bubu');

for( var i = 0; i < bubu.length; i++ ){ bubu[i].addEventListener('click', function(){ console.log( i ); }); } console.log( i );

<button class="bubu">0000</button>
<button class="bubu">1111</button>
<button class="bubu">2222</button>
<button class="bubu">3333</button>
<button class="bubu">4444</button>

Хотелось, чтобы каждая кнопка выводила свой номер - а выводит 5. Это потому что цикл практически моментально сработав - вешает обработчики на все кнопки и заканчивает свою работу. А уже потом, в момент клика, i даже вне цикла, для всех равен 5.

Если не хочется использовать let, можно "поймать" значение i через запущенную на месте функцию:

var bubu = document.querySelectorAll('.bubu');

for( var i = 0; i < bubu.length; i++ ){ (function(i){ //Здесь уже i - не тот же i из цикла, а уже внутренняя переменная для функции //и она равна... bubu[i].addEventListener('click', function(){ console.log( i ); }); })(i);//этому i, который получен прямо из цикла, в момент его выполнения. } console.log( i );

<button class="bubu">0000</button>
<button class="bubu">1111</button>
<button class="bubu">2222</button>
<button class="bubu">3333</button>
<button class="bubu">4444</button>

А let на каждом круге цикла - заново создается и "виден" только на этом круге цикла. Вне цикла - вообще будет undefined:

var bubu = document.querySelectorAll('.bubu');

for( let i = 0; i < bubu.length; i++ ){ bubu[i].addEventListener('click', function(){ console.log( i ); }); } console.log( i ); // ошибка, i is not defined

<button class="bubu">0000</button>
<button class="bubu">1111</button>
<button class="bubu">2222</button>
<button class="bubu">3333</button>
<button class="bubu">4444</button>
OPTIMUS PRIME
  • 27,121
  • 1
    console.log( i ); // ошибка, i is not defined, потому что вы es6 не знаете, нужно let вынести за фигурные скобки. let i = 0; for( ; i < bubu.length; i++ ){ – Андрей Собченюк Aug 21 '19 at 19:08
  • @АндрейСобченюк угу, так и было задумано для демо) Недорассказал в ответе. – OPTIMUS PRIME Aug 22 '19 at 05:58
-1

// es6

const bubu_parent = document.querySelector('.bubu_parent');

const buttons = bubu_parent.querySelectorAll('button');

bubu_parent.addEventListener('click', (e)=> {

const result = Array.from(buttons).findIndex(el =&gt; el === e.target);

   console.log(result);

});

 <div class="bubu_parent">
    <button class="bubu">0000</button>
    <button class="bubu">1111</button>
    <button class="bubu">2222</button>
    <button class="bubu">3333</button>
    <button class="bubu">4444</button>
</div>