2012-05-02 52 views
1

對於上下文,我正在爲omniture(adobe)sitecatalyst寫一個用於視頻跟蹤的插件。在我以sitecatalyst格式編寫插件之前,我想確認它正在工作。我已經測試了相同的代碼,但使用jQuery,並且它可以很好地處理jQuery如何處理變量/作用域。但直接用Javascript來做這件事證明會有點困難。這裏是我在哪裏:JavaScript中的變量範圍AddEventListner

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

} 
} 

在加載時,沒有錯誤(意味着eventlisteners正確連接)。當我按下播放視頻時,我得到一個「vsa [vvv]未定義」。上的代碼與

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

任何想法開始如何讓VSA vp的「全球性」增值經銷商,和S訪問的事件監聽器函數行?

謝謝!

+0

順便說一句,使用數組文字符號'[]'而不是'新陣列'。它更漂亮,並且有更少的邪惡角落案例。 – hugomg

回答

3

變量是可訪問的。問題在於你陷入了圈內陷阱(非常常見)的閉合環境。

基本上,所有的事件監聽器共享相同的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)測試自循環不會運行,如果長度爲零反正...


要在未來aboid這個錯誤,通過像JSHint或JSLint這樣的linter運行你的代碼。如果您在for循環中創建函數,它們會發出警告。

+1

也是不可讀的變量名稱陷阱。 – Domenic

+0

@missingno謝謝。這工作完美(因爲我相信你已經知道)。我很感謝你的回覆。謝謝。 – sol

+0

@Domenic :)完全同意。插件最終寫入的方式最終需要儘可能的「短手」。但原則上,我完全同意你的看法。 – sol