我正在尝试在视频中设置多个提示点。我不想编写每个提示,而是迭代一个拥有我需要的数据的对象,例如提示的时间和一些关于如何处理回调的信息。
问题是,当我尝试迭代对象时,它会覆盖除最后一个之外的所有提示。
var products = myVideo.products;
var video = Popcorn('#mainVideo');
for (product in products){
var obj = products[product],
start = obj.start,
img = obj.image,
$targetDiv = $("#"+obj.targetDiv);
video.cue( start, function(){
$('<img>', {
class : "isImage",
src : 'images/' + img
}).prependTo( $targetDiv );
})
}
非常感谢任何帮助。
答案 0 :(得分:3)
在此代码中,每个cue都有自己的回调函数,但每个函数都引用相同的变量img
和相同的$targetDiv
。当它们运行时,这些变量将被设置为products
中最后一项的各自值。
如果您曾经通过jslint运行代码并看到警告,请不要在循环中创建函数,这就是原因。做你想要做的事情的一个好方法是将这些变量放在一个立即被调用的函数中,然后返回另一个函数,即你的回调函数。像这样:
function makeCallback(obj) {
return function() {
$('<img>', {
class : "isImage",
src : 'images/' + obj.img
}).prependTo( $("#"+obj.targetDiv) );
};
}
for (var product in products) {
var obj = products[product];
video.cue( obj.start, makeCallback( obj ) );
}
或者,您可以使用forEach,它在幕后做同样的事情。 (爆米花提供its own version,它处理数组和对象。)
Popcorn.forEach(products, function(obj) {
video.cue( start, function(){
$('<img>', {
class : "isImage",
src : 'images/' + obj.img
}).prependTo( $("#"+obj.targetDiv) );
});
});
我应该注意到你在这段代码中还有另一个问题,那就是每当你通过提示点时,你都会让Popcorn创建一个新的图像。因此,如果用户跳过重播某些视频,图像将开始堆积。此外,图像直到它们变得可见时才会开始加载,因此如果网络连接速度较慢,则图像可能会显示,直到它为时已晚。
处理这些问题的最佳方法通常是提前创建图像,但使用CSS隐藏它们,然后让Popcorn事件在正确的时间显示它们。您可以考虑使用image插件,这将为您完成大部分繁重工作。