2012-05-02 31 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