2009-04-14 177 views
5

我已阅读了许多关于此的帖子,但没有任何可靠的答案。这里是我的代码:setAttribute,onClick和跨浏览器兼容性

// 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方法时,我确实改变了函数调用,并且它仅使用一个简单的调用alert函数就能正常工作,这就是为什么我相信我的语法不正确。长话短说,我不能让onclick参数在IE/Mozilla之间一致地工作。

- 尼古拉斯

回答

6

我通常使用类似:

onew.onclick = new Function("fnDisplay_Computers('" + alines[i] + "')"); 

这应该在IE火狐ë工作两者。

+0

这完美的作品,你能解释一下为什么设置它为“新功能”(即使函数fnDisplay_Computers()”是否已经定义,解决了这个问题? – 2009-04-14 19:24:34

+0

我认为这是一个涉及到的数据类型的问题,以及与新的onclick方法相关的“新函数”的引用......但我真的不知道确切的答案,对不起! – 2009-04-14 19:28:36

1

使用addEventListener()功能与“click”为type参数用于基于Mozilla的浏览器,并以“onclickattachEvent()函数作为sEvent参数的IE;我觉得最好用try/catch语句,例如:

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); 
} 
15

onew.setAttribute(“type”,“button”);

不要在HTML文档上使用setAttribute。 IE得到它在许多情况下严重错误,和DOM-HTML属性是较短的,更快速,更容易阅读:

onew.type= 'button'; 

onew.onclick =函数(){fnDisplay_Computers( “'” + ALINES [I ] +“'”); }; // ie

'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)) 
      ); 
     }; 
    }; 
} 
0

我觉得#3 protesteth太多。在很多情况下,我正在动态构建一个表,并且需要将参数传递给回调函数。这不是一个类型安全问题,因为我的变量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); 
}