1

我很肯定我以错误的方式问了这个问题。我正在尝试将字符串传递onClick="someFunc(arg1,arg2...)"给 javascript 解析器。

解析器应该为带有 args (arg1, arg2 etc) 的 someFunc 创建一个 onClick 事件。

我的问题是,当文本通过解析器传递时,保存 someFunc 字符串名称的变量的范围正在被传递,以便附加事件都注册为最后声明的字符串。

在下面的代码中,attributes._onClick 可以是字符串 'onClick="someFunc(arg1,arg2);" 对于一个元素,后跟 'onClick="otherFunc(argA,argB);" 对于另一个元素,因为解析器在字符串中移动。

浏览器 (Firefox V14.01) 中的输出具有始终注册为 otherFunc 的事件函数。所以闭包中的 f_name 不是作为变量进行评估,而是只是注册为在整个块解析过程中声明的 f_name 的最后一个值。

我不熟悉范围到我需要弄清楚这一点的程度。有谁知道我可以以这种方式附加事件的方法(我试图避免超出解析器来添加事件)?

           temp = attributes._onClick ;
            var x = 0 ;
            var f_name,f_args ;
            while(temp[x] != '') {
                temp[x] = temp[x].replace(')','').split('(') ;//remove paranthesis and separate func name from args
                f_name = temp[x][0] ;
                f_args = temp[x][1].split(',') ;//turn string of args into array
                el.onclick = function() { window[f_name].apply(el,f_args) ; }
                x++ ;
            }
4

1 回答 1

0

您正在绊倒 JavaScript 中的一个陷阱,该陷阱在某些时候以各种不同的方式对几乎每个人造成相同的问题。

变量“f_name”在您创建的所有函数之间共享。也就是说,虽然循环的每次迭代都会创建一个新函数,但只有一个“f_name”。因此,所有函数都在其中看到相同的值,即上次迭代时的值。

有几个相关的解决方案。一种方法是将建立事件处理程序的语句包装在另一个匿名函数中,您可以立即调用该函数。这将允许您创建一个“f_name”的副本,供一个处理程序独占使用。

               el.onclick = function(name) {
                return function() { window[name].apply(el,f_args) ; };
               }(f_name);

有趣的是,这个问题在 SO 上可能有数百种变体。

于 2012-07-31T18:00:39.890 回答