Почему я не могу установить обработчики массовых событий?

0

Так что эти две работы отлично работают:

$(document).on("click", "#_something", function(){
    $('#vid').attr('src',video_config["something"].video);

});
$(document).on("click", "#_anotherthing", function(){
    $('#vid').attr('src',video_config["anotherthing"].video);

});

Однако something и nothing является свойствами объекта, который я создал, поэтому я попытался сделать это:

for (var key in video_list){
    $(document).on("click", "#_"+key, function(){
        $('#vid').attr('src',video_list[key].video);
    });
}

Какой из них он испортил и установил все значения src в последнее значение video_list[key].video меня есть. Чтобы перефразировать, это присвоило всем свойствам src одинаковое значение.

Как это сделать правильно, без ручной записи каждого из обработчиков событий?

  • 2
    Используйте классы вместо идентификаторов.
  • 0
    наличие более одного #vid испортит все
Показать ещё 2 комментария
Теги:

3 ответа

4
Лучший ответ

Это связано с тем, что функция Handler захватывает key переменную, которая привязана к родительской функции. Когда ваш обработчик выполняет, key имеет последнее значение.

Исправление состоит в том, чтобы зафиксировать текущее значение на каждой итерации, используя еще одну область функций. Как это:

for (var k in video_list) {
  function(key) {
    // create your event handler here using key
  }(k);
}

Это объясняется в этом вопросе, который в основном такой же, как и этот: закрытие javascript в цикле for

В браузерах ES6, let блокировать область, вы можете использовать ее как ярлык:

for (let k in video_list) {
  let key = k;
  // same code as your question goes here, using key.
}
  • 0
    let не поддерживается в большинстве браузеров
  • 0
    Вот почему я сказал в браузерах ES6 . Кроме того, большинство браузеров зависит от вашей целевой аудитории: он поддерживается IE11 +, как минимум FF24 + и как минимум Chrome 30+. Что касается совместимости с ES6, вы можете посмотреть таблицы совместимости с Kangax : kangax.github.io/es5-compat-table/es6/#let
Показать ещё 6 комментариев
2

Здесь простой способ использования одного обработчика события, класса и атрибута данных:

$(document).on("click", ".video", function(){
    var key = $(this).data("key"); // in the element add data-key="xyz"
    $('#vid').attr('src',video_list[key].video);
});
1

Быстрый и грязный взлом:

for (var key in video_list){
    (function(key){// create a new context, so not all handlers point the the same key
        $(document).on("click", "#_"+key, function(){
            $('#vidSrc').attr('src',video_list[key].video);
        });
    })(key);
}

Правильный способ:

$(document).on("click", ".some-new-class-you-just-defined", function() {
    $(this).attr('src', video_list[$(this).attr('id').slice(1)].video);
});

EDIT: добавьте подстроку в идентификатор. Лучше иметь какой-то механизм поиска, а не хранить его в id, как предлагалось @jods.

  • 1
    Ваш второй фрагмент кода неверен, потому что id начинается с дополнительного подчеркивания _ а не с необработанного имени свойства. Немного возиться нужно. Это довольно странно, если вы идете по этому пути, вы должны поместить имя свойства в дополнительный атрибут, например data-videokey=something .
  • 0
    +1 Используйте классы не цикл
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню