Есть массив объявлений, к каждому из которых генерируется метка на карте и карточка к ней. При клике на метку, должна отобразиться соответствующая ей карточка. Следующий код срабатывает как надо:
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");
})
});
В этом случае при клике на любую метку отображается та карточка, которая была последней в цикле. Может быть, кто-нибудь может объяснить с чем связано такое поведение?
Здесь не важно, какой код, важно поведение 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>
// 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 => 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>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Я пользуюсь VS Code и там же запускаю localhost для авто перезагрузки страницы (после сохранения файла)Но проблема в том, что после этой перезагрузки...
Необходимо реализовать алгоритм проверяющий наличие подстроки в массиве строк и возвращающая номера элементов массива, в которых встретилась...