3

我正在尝试在视频中设置多个提示点。我不想将每个提示都写出来,而是想遍历一个包含我需要的数据的对象,例如提示的时间以及有关如何处理回调的一些信息。

问题是当我尝试迭代对象时,它会覆盖除最后一个之外的所有提示。

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 );
        })

    }

任何帮助将不胜感激。

4

1 回答 1

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,它在引擎盖下做同样的事情。(Popcorn 提供了自己的版本,它同时处理数组和对象。)

Popcorn.forEach(products, function(obj) {
    video.cue( start, function(){
        $('<img>', {
        class : "isImage",
        src : 'images/' + obj.img
        }).prependTo( $("#"+obj.targetDiv) );
    });
});

我应该注意到,这段代码还有另一个问题,即每次通过提示点时,爆米花都会创建一个新图像。因此,如果用户跳回回放某些视频,图像就会开始堆积。此外,图像直到它们变得可见时才会开始加载,因此如果网络连接速度较慢,图像可能不会显示,直到为时已晚。

处理这些问题的最佳方法通常是提前创建图像,但使用 CSS 使它们不可见,然后让 Popcorn 事件在正确的时间使它们可见。您可能会考虑使用图像插件,它将为您完成大部分繁重的工作。

于 2013-01-29T15:27:14.807 回答