我已经阅读了很多关于此的帖子,但没有任何可靠答案。这是我的代码:
// button creation
onew = document.createElement('input');
onew.setAttribute("type", "button");
onew.setAttribute("value", "hosts");
onew.onclick = function(){fnDisplay_Computers("'" + alines[i] + "'"); }; // ie
onew.setAttribute("onclick", "fnDisplay_Computers('" + alines[i] + "')"); // mozilla
odiv.appendChild(onew);
现在,setAttribute()方法(带有mozilla注释)在mozilla中工作正常,但只有在它上面的行之后才会出现。换句话说,它似乎只是默认为最后设置的那个。 .onclick方法(使用ie注释)在任何一种情况下都不起作用,我使用不正确吗?
无论哪种方式,我都无法找到在IE中完成这项工作的方法,更不用说两种方式了。我在使用.onclick方法时确实更改了函数调用,只需简单调用一个警报函数就可以正常工作,这就是为什么我认为我的语法不正确。
长话短说,我无法让onclick参数在IE / Mozilla之间保持一致。
- 尼古拉斯
答案 0 :(得分:15)
onew.setAttribute(“type”,“button”);
永远不要在HTML文档上使用setAttribute。 IE在许多情况下都会出现严重错误,并且DOM-HTML属性更短,更快,更易于阅读:
onew.type= 'button';
onew.onclick = function(){fnDisplay_Computers(“'”+ alines [i] +“'”); }; //即
什么是'alines'?为什么要将它转换为字符串并用单引号将其包围?看起来你正在尝试做一些令人发指的事情,包括在字符串中评估代码(这是你在'onew.setAttribute'版本中所做的)。在字符串中评估JavaScript代码几乎总是错误的事情;像瘟疫一样避免它。在上面的例子中,IE应该和Firefox一样:它应该不起作用。
如果'alines [i]'是一个字符串,我想你要做的是让它通过构造一个代码字符串来记住该字符串,该代码字符串将在JavaScript中评估原始字符串。但是:
"'" + alines[i] + "'"
不足。如果'alines [i]'有撇号或反斜杠会怎么样?
'O'Reilly'
你有语法错误和可能的安全漏洞。现在,你可以做一些艰苦而烦人的事情,如:
"'" + alines[i].split('\\').join('\\\\').split("'").join("\\'") + "'"
尝试转义字符串,但它很丑,不适用于其他数据类型。你甚至可以让JavaScript为你做这件事:
uneval(alines[i])
但并非所有对象都可以转换为可评估的JavaScript源字符串;基本上整个方法都注定要失败。
如果您只想让onclick回调调用带参数的函数,那么通常要做的就是以直接的方式编写代码:
onew.onclick= function() {
fnDisplay_Computers(alines[i]);
};
一般情况下这会起作用并且是你想要的。然而,你可能会在这里遇到一些轻微的皱纹,这可能会令你感到困惑,因为你会考虑使用弦乐的古怪方法。
即,如果在这种情况下'i'是包含'for'循环的变量,则对'alines [i]'的引用将不会按照您的想法执行。当点击发生时,回调函数将访问'i' - 在循环完成后。此时'i'变量将保留其在循环结束时的任何值,因此'alines [i]'将始终是'alines'的最后一个元素,无论单击哪个'onew'。
(参见例如How to fix closure problem in ActionScript 3 (AS3)对此进行一些讨论。这是与JavaScript和Python中的闭包混淆的最大原因之一,并且有一天应该在语言层面得到修复。)
您可以通过将闭包封装在自己的函数中来解决循环问题,如下所示:
function callbackWithArgs(f, args) {
return function() { f.apply(window, args); }
}
// ...
onew.onclick= callbackWithArgs(fnDisplay_Computers, [alines[i]]);
在更高版本的JavaScript中,您可以简单地说:
onew.onclick= fnDisplay_Computers.bind(window, alines[i]);
如果您希望今天能够在浏览器中使用'Function.bind()',您可以从Prototype框架获得实现,或者只使用:
if (!('bind' in Function.prototype)) {
Function.prototype.bind= function(owner) {
var that= this;
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner,
args.length===0? arguments : arguments.length===0? args :
args.concat(Array.prototype.slice.call(arguments, 0))
);
};
};
}
答案 1 :(得分:6)
我通常使用类似的东西:
onew.onclick = new Function("fnDisplay_Computers('" + alines[i] + "')");
这应该适用于IE e Firefox。
答案 2 :(得分:1)
对于基于Mozilla的浏览器的click
参数,使用带有“type
”的addEventListener()
函数,将带有“onclick
”的attachEvent()
功能用作sEvent
IE的try {
onew.attachEvent("onclick", //For IE
function(){fnDisplay_Computers("'" + alines[i] + "'"); });
}
catch(e) {
onew.addEventListener("click", //For Mozilla-based browsers
function(){fnDisplay_Computers("'" + alines[i] + "'"); },
false);
}
参数;我发现最好使用try / catch语句,例如:
{{1}}
答案 3 :(得分:0)
我认为#3抗议太多了。在很多情况下,我正在动态构建一个表,需要将参数传递给回调函数。它不是类型安全的问题,因为我的变量parm是相关表行的整数索引。这里的代码包含一个变量和固定参数,似乎是跨浏览器兼容的:
for (i = 0; i < arrTableData.length; i++) {
eleTR = objTable.insertRow(i + 1);
cell = eleTR.insertCell(0);
cell.width = "21";
var myElement = document.createElement('img');
myElement.setAttribute('src', 'images/button_down.gif');
myElement.setAttribute('alt', 'Move item down');
myElement.onclick = new Function('moveItem(' + i + ',0)');
cell.appendChild(myElement);
}