Так что эти две работы отлично работают:
$(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
одинаковое значение.
Как это сделать правильно, без ручной записи каждого из обработчиков событий?
Это связано с тем, что функция 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.
}
let
не поддерживается в большинстве браузеров
Здесь простой способ использования одного обработчика события, класса и атрибута данных:
$(document).on("click", ".video", function(){
var key = $(this).data("key"); // in the element add data-key="xyz"
$('#vid').attr('src',video_list[key].video);
});
Быстрый и грязный взлом:
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.
id
начинается с дополнительного подчеркивания _
а не с необработанного имени свойства. Немного возиться нужно. Это довольно странно, если вы идете по этому пути, вы должны поместить имя свойства в дополнительный атрибут, например data-videokey=something
.