gpt4 book ai didi

javascript - JavaScript AddEventListener 中的变量作用域

转载 作者:行者123 更新时间:2023-11-30 13:20:22 24 4
gpt4 key购买 nike

对于上下文,我正在为 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] 未定义”。在以

开头的代码行
if(!vp[vsa[vvv].id]) 

关于如何从事件监听器函数中获取 vsa、vp 和 s 的“全局”变量,有什么想法吗?

谢谢!

最佳答案

变量是可访问的。问题是您陷入了 for 循环陷阱中的(非常常见的)闭包。

基本上,所有事件监听器都共享同一个 vvv 变量。到事件监听器运行时,vvv 已完成所有循环并设置为 vsa.length,从而使 vsa[vvv] 未定义。 (通过向事件监听器添加 console.log(vvv) 调用来检查这一点)

通常的解决方法是在循环外的函数中创建事件监听器,以使每个事件监听器获得自己对视频标签变量的引用。

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 等 linter 运行您的代码。如果您在 for 循环内创建函数,它们会发出警告。

关于javascript - JavaScript AddEventListener 中的变量作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10407892/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com