1

コンテキストとして、ビデオ追跡用の omniture (adobe) sitecatalyst のプラグインを作成しています。プラグインを sitecatalyst 形式で作成する前に、プラグインが機能していることを確認したいと思います。jQueryを使用して同じコードをテストしましたが、jQueryが変数/スコープを処理する方法で問題なく動作します。しかし、Javascript で直接行うのは少し難しいことがわかっています。これが私がいる場所です:

var vsa = new Array();
var vp = new Array(); 
vsa = document.getElementsByTagName('video');
if(vsa.length>0){
for(var vvv=0;vvv<vsa.length;vvv++) {
    vsa[vvv].addEventListener('seeked',function () { if(vp[vsa[vvv].id]) { s.Media.play(vsa[vvv].id,vsa[vvv].currentTime); }},false);
    vsa[vvv].addEventListener('seeking',function () { if(vp[vsa[vvv].id]) { s.Media.play(vsa[vvv].id,vsa[vvv].currentTime); }},false);
    vsa[vvv].addEventListener('play',function () { 
        if(!vp[vsa[vvv].id]) { 
            vp[vsa[vvv].id] = true; 
            s.Media.open(vsa[vvv].id,vsa[vvv].duration,s.Media.playerName);
            s.Media.play(vsa[vvv].id,vsa[vvv].currentTime); 
        } else {
            s.Media.play(vsa[vvv].id,vsa[vvv].currentTime);
        }},false);
    vsa[vvv].addEventListener('pause',function () { if(vp[vsa[vvv].id]) { s.Media.stop(vsa[vvv].id,vsa[vvv].currentTime); }},false);
    vsa[vvv].addEventListener('ended',function () { vp[vsa[vvv].id] = false; s.Media.stop(vsa[vvv].id,vsa[vvv].currentTime); s.Media.close(vsa[vvv].id); },false);

    if (typeof vsa[vvv].error != 'undefined' && vsa[vvv].error) {
        var scvt_msg = 'Error Not Captured';
        if(typeof vsa[vvv].error.code != 'undefined') {
            switch (vsa[vvv].error.code) {
                case MEDIA_ERR_ABORTED:
                    scvt_msg = 'vsa[vvv]eo stopped before load.';
                    break;
                case MEDIA_ERR_NETWORK:
                    scvt_msg = 'Network error';
                    break;
                case MEDIA_ERR_DECODE:
                    scvt_msg = 'vsa[vvv]eo is broken';
                    break;  
                case MEDIA_ERR_SRC_NOT_SUPPORTED:
                    scvt_msg = 'Codec is unsupported by this browser';
                    break;
            }
        }
        s.tl(this,'o','video: ' + scvt_msg);
    }

}
}

読み込み時にエラーは発生しません (イベントリスナーが正しくアタッチされていることを意味します)。ビデオの再生を押すと、「vsa [vvv] is undefined」が表示されます。で始まるコード行で

if(!vp[vsa[vvv].id]) 

イベントリスナー関数からアクセス可能なvsa、vp、およびsの「グローバル」変数を取得する方法はありますか?

ありがとうございました!

4

1 に答える 1

3

変数にアクセスできます。問題は、 for ループ トラップ内の (非常に一般的な) クロージャに陥ったことです。

基本的に、すべてのイベント リスナーは同じ vvv 変数を共有しています。イベント リスナーが実行されるまでに、vvv はすべてのループを通過し、vsa.length に設定され、vsa[vvv] が未定義になります。console.log(vvv)(イベントリスナーへの呼び出しを追加して確認してください)

これに対する通常の修正は、ループの外側の関数でイベント リスナーを作成して、各イベント リスナーが videotag 変数への独自の参照を取得するようにすることです。

function addMyEvents(node){
    //the inner functions here get their own separate version of "node"
    // instead of sharing the vvv
    node.addEventListener('seeked',function () { if(vp[node.id]) { s.Media.play(node.id, node.currentTime); }},false);
    node.addEventListener('seeking',function () { if(vp[node.id]) { s.Media.play(node.id, node.currentTime); }},false);
    //...
}

for(var vvv=0;vvv<vsa.length;vvv++) {
    addMyEvents(vsa[vvv]);
}

ちなみに、if(vsa.length)とにかく長さがゼロの場合、ループは実行されないため、最初にテストは必要ありません...


今後このエラーを回避するには、JSHint や JSLint などのリンターを使用してコードを実行してください。for ループ内で関数を作成すると、警告が表示されます。

于 2012-05-02T04:52:28.350 に答える