#javascript #jquery
#javascript #jquery
Вопрос:
Я недавно начал учиться программировать, и у меня возникла проблема с этим самоконтролем. Я намерен использовать цикл for для циклического перебора массива, содержащего названия цветов, которые представляют кнопки, для создания динамического URL-адреса аудиофайлов вместо индивидуального добавления URL-адреса аудиофайла к каждой кнопке. Будучи новичком, этот код имеет смысл для меня, но он не работает. Используя инструмент «проверка» браузера, я заметил, что вывод for buttonColours[i]
отображается как undefined . Пожалуйста, помогите мне понять, почему!!!
var buttonColours = ["red","blue","green","yellow"];
var sounds = [];
for (var i = 0; i < buttonColours.length; i ){
$("." buttonColours[i] "").click(function(event){
// Add sound when button is clicked
sounds[i]= new Audio("sounds/" buttonColours[i] ".mp3");
sounds[i].play();
// Add CSS class when button is clicked
$(".red").addClass("pressed");
setTimeout(function(){
$(".red").removeClass("pressed");
}, 200);
});
}
Комментарии:
1. Когда выполняется скрипт?
$("." buttonColours[i] "").click(...
Строка попытается найти элемент на странице. Если код выполняется до загрузки страницы (например, вы поместили его в<script>
тег в<head>
разделе вашей страницы), элемент не будет существовать и будет существоватьundefined
.
Ответ №1:
В дополнение к правильному ответу Сачина Наяка, другим способом решения этой проблемы является использование let
вместо var
. let
создает переменную внутри области действия цикла, где var
будет глобальная переменная, которая будет перезаписываться на каждой итерации. Это означает, что при let
использовании вы не перезаписываете значение, а создаете новое на каждой итерации, таким образом, ссылка остается неизменной.
var buttonColours = ["red","blue","green","yellow"];
var sounds = [];
// Notice let i instead of var i.
for (let i = 0; i < buttonColours.length; i ) {
$("." buttonColours[i]).click(function(event) {
// Add sound when button is clicked
sounds[i] = new Audio("sounds/" buttonColours[i] ".mp3");
sounds[i].play();
// Add CSS class when button is clicked
$(".red").addClass("pressed");
setTimeout(function() {
$(".red").removeClass("pressed");
}, 200);
});
}
Ответ №2:
Поскольку функция click является обратным вызовом, переменная i, возможно, была изменена до того, как произошел обратный вызов. Таким образом, вам придется привязать значение i к функции. Попробуйте это вместо :
var buttonColours = ["red", "blue", "green", "yellow"];
var sounds = [];
for (var i = 0; i < buttonColours.length; i ) {
$("." buttonColours[i] "").click(function(i, event) { // OBSERVE i have added i as a parameter
// Add sound when button is clicked
sounds[i] = new Audio("sounds/" buttonColours[i] ".mp3");
sounds[i].play();
// Add CSS class when button is clicked
$(".red").addClass("pressed");
setTimeout(function() {
$(".red").removeClass("pressed");
}, 200);
}.bind(this, i)); // OBSERVE I have added an i here
}
Еще одна проблема, с которой вы сталкиваетесь в своем коде, заключается в том, что вы не инициализировали массив звуков. Я не думаю, что это приведет к ошибке, поэтому я не исправил это.
Эта статья, похоже, хорошо объясняет проблему: https://www.pluralsight.com/guides/javascript-callbacks-variable-scope-problem