Как создать динамический URL для аудиофайлов с помощью цикла for? Javascript

#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