2012-05-02 5 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] is undefined"가 나타납니다. 이벤트 리스너 함수에서 어떻게 VSA, 부사장의 "글로벌"바르를 얻을 수

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

어떤 아이디어로 시작, 접근이야 코드의 라인?

감사합니다.

+0

사실,'new Array' 대신 배열 리터럴 표기법'[]'을 사용하십시오. 그것은 더 예쁘고 사악한 경우가 적습니다. – hugomg

답변

3

변수에 액세스 할 수 있습니다. 문제는 당신이 루프 트랩 내부의 (매우 일반적인) 클로저에 빠졌다는 것입니다.

기본적으로 모든 이벤트 수신기는 동일한 vvv 변수를 공유합니다. 이벤트 리스너가 실행될 때까지 vvv는 모든 루프를 통과했으며 vsa [vvv]가 정의되지 않도록 vsa.length로 설정되었습니다. (이벤트 청취자에게 console.log(vvv) 콜을 추가하여 이것을 확인하십시오.)

일반적인 수정은 루프 외부의 함수에 이벤트 리스너를 생성하여 각 이벤트 리스너가 비디오 태그 변수에 대한 자체 참조를 얻도록하는 것입니다. 길이가 어쨌든 0 인 경우 루프가 늘 실행 이후

그런데
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]); 
} 

, 당신은


미래에이 오류를 aboid하기 위해 ... 처음에 if(vsa.length) 테스트가 필요하지 않습니다 JSHint 또는 JSLint와 같은 linter를 통해 코드를 실행하십시오. for 루프 내부에 함수를 작성하면 경고가 표시됩니다.

+1

읽을 수없는 변수 이름 트랩. – Domenic

+0

@missingno 감사합니다. 이것은 완벽하게 (당신이 이미 알고 있다고 확신했기 때문에) 효과가있었습니다. 회신 해 주셔서 감사합니다. 고맙습니다. – sol

+0

@Domenic :) 전적으로 동의합니다. 플러그인을 작성하는 방법은 가능한 한 많은 "짧은 손"을 필요로합니다. 그러나 원칙적으로 나는 당신에게 전적으로 동의한다. – sol