setAttribute,onClick和跨浏览器兼容性

时间:2009-04-14 19:10:25

标签: 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.setAttribute("onclick", "fnDisplay_Computers('" + alines[i] + "')"); // mozilla
odiv.appendChild(onew);

现在,setAttribute()方法(带有mozilla注释)在mozilla中工作正常,但只有在它上面的行之后才会出现。换句话说,它似乎只是默认为最后设置的那个。 .onclick方法(使用ie注释)在任何一种情况下都不起作用,我使用不正确吗?

无论哪种方式,我都无法找到在IE中完成这项工作的方法,更不用说两种方式了。我在使用.onclick方法时确实更改了函数调用,只需简单调用一个警报函数就可以正常工作,这就是为什么我认为我的语法不正确。

长话短说,我无法让onclick参数在IE / Mozilla之间保持一致。

- 尼古拉斯

4 个答案:

答案 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);
}