Ajax setAttribute、onClick和跨浏览器兼容性

Ajax setAttribute、onClick和跨浏览器兼容性,ajax,dom,setattribute,Ajax,Dom,Setattribute,我读过很多关于这方面的帖子,但没有一篇有可靠的答案。这是我的密码: // button creation onew = document.createElement('input'); onew.setAttribute("type", "button"); onew.setAttribute("value", "hosts"); onew.onclick = function(){fnDisplay_Computers("'" + alines[i] + "'"); }; // ie onew

我读过很多关于这方面的帖子,但没有一篇有可靠的答案。这是我的密码:

// 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之间保持一致

--Nicholas

对于基于Mozilla的浏览器,使用带有“
单击
”的函数作为
类型
参数,对于IE,使用带有“
onclick
”的函数作为
sEvent
参数;我发现最好使用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);
}

我通常会使用类似于:

onew.onclick = new Function("fnDisplay_Computers('" + alines[i] + "')");
这应该在IE和Firefox中都适用

一个新的setAttribute(“类型”、“按钮”)

切勿在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”

(关于这方面的一些讨论,请参见示例。这是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()”,您可以从框架中获得一个实现,或者只使用:

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))
            );
        };
    };
}
我认为#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);
}
for(i=0;i
这项功能非常有效,您能解释一下为什么将其设置为“新函数”(即使已经定义了函数fnDisplay\u Computers())可以解决问题吗?我认为这是涉及的数据类型和对“新函数”的引用的问题“与新的onclick方法相关……但我真的不知道确切答案,抱歉!太好了!谢谢!IE7有问题,这完美地解决了它。回答很好,哇,你涵盖了所有的碱基。幸运的是,在alines[x]之前字符串都经过消毒。”甚至被引用,并且传入的值无论如何都是已定义数组的一部分,因此无需担心。可以安全地说:onclick是一个事件处理程序,而不是一个属性,因此将其设置为属性将不会创建所需的事件处理程序,使其至少在IE下工作?是的。它实际上是一个本机脚本ent handler属性(函数类型)和文档级属性(字符串类型),但由于IEB非常优秀,我得到了它。非常感谢您的输入。