今天遇到这个问题,发帖以防其他人也有同样的问题。

var execBtn = document.createElement('input');
execBtn.setAttribute("type", "button");
execBtn.setAttribute("id", "execBtn");
execBtn.setAttribute("value", "Execute");
execBtn.setAttribute("onclick", "runCommand();");

结果是让 IE 在动态生成的元素上运行 onclick,我们不能使用 setAttribute。相反,我们需要使用包装我们要运行的代码的匿名函数来设置对象的 onclick 属性。

execBtn.onclick = function() { runCommand() };

坏主意:

你可以做

execBtn.setAttribute("onclick", function() { runCommand() });

但根据 @sunliffe 的说法,它会在非标准模式下的 IE 中崩溃。

你根本不能这样做

execBtn.setAttribute("onclick", runCommand() ); 

因为它会立即执行,并将runCommand()的结果设置为onClick属性值,你也不能这样做

execBtn.setAttribute("onclick", runCommand);
有帮助吗?

解决方案

要使此功能在 FF 和 IE 中都有效,您必须以两种方式编写:


    button_element.setAttribute('onclick','doSomething();'); // for FF
    button_element.onclick = function() {doSomething();}; // for IE

谢谢 这个帖子.

更新: :这是为了证明有时 必须使用setAttribute!如果您需要从 HTML 中获取原始 onclick 属性并将其添加到 onclick 事件中,这样它就不会被覆盖,则此方法有效:

// get old onclick attribute
var onclick = button_element.getAttribute("onclick");  

// if onclick is not a function, it's not IE7, so use setAttribute
if(typeof(onclick) != "function") { 
    button_element.setAttribute('onclick','doSomething();' + onclick); // for FF,IE8,Chrome

// if onclick is a function, use the IE7 method and call onclick() in the anonymous function
} else {
    button_element.onclick = function() { 
        doSomething();
        onclick();
    }; // for IE7
}

其他提示

有一个 大的 你的属性集合 IE中无法设置 使用 .setAttribute() 其中包括每个内联事件处理程序。

详细信息请参见此处:

http://webbugtrack.blogspot.com/2007/08/bug-242-setattribute-doesnt-always-work.html

效果很好!

现在似乎没有必要使用这两种方式:

execBtn.onclick = function() { runCommand() };

显然适用于当前的每个浏览器。

在 Windows 上当前的 Firefox、IE、Safari、Opera、Chrome 中进行了测试;Ubuntu上的Firefox和Epiphany;未在 Mac 或移动系统上进行测试。

  • 克雷格:我会尝试“document.getElementById(ID).type='password';
  • 有没有人检查过不同引擎的“AddEventListener”方法?

对于跨浏览器兼容的事件绑定来说,这是一个令人惊奇的功能。

从那里得到的 http://js.isite.net.au/snippets/addevent

有了它你就可以做 Events.addEvent(element, event, function); 无忧无虑!

例如:(http://jsfiddle.net/Zxeka/)

function hello() {
    alert('Hello');
}

var button = document.createElement('input');
button.value = "Hello";
button.type = "button";

Events.addEvent(input_0, "click", hello);

document.body.appendChild(button);

这是函数:

// We create a function which is called immediately,
// returning the actual function object.  This allows us to
// work in a separate scope and only return the functions
// we require.
var Events = (function() {

  // For DOM2-compliant browsers.
  function addEventW3C(el, ev, f) {
    // Since IE only supports bubbling, for
    // compatibility we can't use capturing here.
    return el.addEventListener(ev, f, false);
  }

  function removeEventW3C(el, ev, f) {
    el.removeEventListener(ev, f, false);
  }

  // The function as required by IE.
  function addEventIE(el, ev, f) {
    // This is to work around a bug in IE whereby the
    // current element doesn't get passed as context.
    // We pass it via closure instead and set it as the
    // context using call().
    // This needs to be stored for removeEvent().
    // We also store the original wrapped function as a
    // property, _w.
    ((el._evts = el._evts || [])[el._evts.length]
        = function(e) { return f.call(el, e); })._w = f;

    // We prepend "on" to the event name.
    return el.attachEvent("on" + ev,
        el._evts[el._evts.length - 1]);
  }

  function removeEventIE(el, ev, f) {
    for (var evts = el._evts || [], i = evts.length; i--; )
      if (evts[i]._w === f)
        el.detachEvent("on" + ev, evts.splice(i, 1)[0]);
  }

  // A handler to call all events we've registered
  // on an element for legacy browsers.
  function addEventLegacyHandler(e) {
    var evts = this._evts[e.type];
    for (var i = 0; i < evts.length; ++i)
      if (!evts[i].call(this, e || event))
        return false;
  }

  // For older browsers.  We basically reimplement
  // attachEvent().
  function addEventLegacy(el, ev, f) {
    if (!el._evts)
      el._evts = {};

    if (!el._evts[ev])
      el._evts[ev] = [];

    el._evts[ev].push(f);

    return true;
  }

  function removeEventLegacy(el, ev, f) {
    // Loop through the handlers for this event type
    // and remove them if they match f.
    for (var evts = el._evts[ev] || [], i = evts.length; i--; )
      if (evts[i] === f)
        evts.splice(i, 1);
  }

  // Select the appropriate functions based on what's
  // available on the window object and return them.
  return window.addEventListener
      ? {addEvent: addEventW3C, removeEvent: removeEventW3C}
      : window.attachEvent
          ? {addEvent: addEventIE, removeEvent: removeEventIE}
          : {addEvent: addEventLegacy, removeEvent: removeEventLegacy};
})();

如果你不想使用这么大的功能,这应该适用于几乎所有浏览器,包括 IE:

if (el.addEventListener) { 
    el.addEventListener('click', function, false); 
} else if (el.attachEvent) { 
    el.attachEvent('onclick', function); 
} 

回答克雷格的问题。您将必须创建一个新元素并复制旧元素的属性。这个函数应该完成以下工作:(来源)

function changeInputType(oldObject, oType) {
  var newObject = document.createElement('input');
  newObject.type = oType;
  if(oldObject.size) newObject.size = oldObject.size;
  if(oldObject.value) newObject.value = oldObject.value;
  if(oldObject.name) newObject.name = oldObject.name;
  if(oldObject.id) newObject.id = oldObject.id;
  if(oldObject.className) newObject.className = oldObject.className;
  oldObject.parentNode.replaceChild(newObject,oldObject);
  return newObject;
}

或者你可以使用 jQuery 并避免所有这些问题:

var execBtn = $("<input>", {
       type: "button",
       id: "execBtn",
       value: "Execute"
    })
    .click(runCommand);        

jQuery 还将解决所有跨浏览器问题。

实际上,据我所知,动态创建的内联事件处理程序在使用 Internet Explorer 8 创建时可以完美地工作 x.setAttribute() 命令;你只需要将它们正确地放置在 JavaScript 代码中即可。我偶然发现了你的问题(和我的)的解决方案 这里.

当我移动所有包含以下内容的语句时 x.appendChild() 到它们的正确位置(即,紧随其组中的最后一个 setAttribute 命令之后),我发现每个 setAttribute 在 IE8 中都按预期工作,包括所有表单输入属性(包括“名称”和“类型”属性,如以及我的“onclick”事件处理程序)。

我发现这非常了不起,因为在我这样做之前,我在 IE 中遇到的只是屏幕上呈现的垃圾,以及一个又一个错误。此外,我发现每个 setAttribute 仍然可以在其他浏览器中工作,因此,如果您只记住这个简单的编码实践,那么在大多数情况下您就可以很好地进行操作。

但是,如果您必须即时更改任何属性,则此解决方案将不起作用,因为一旦将 HTML 元素附加到 DOM,就无法在 IE 中更改它们;在这种情况下,我想象必须从 DOM 中删除该元素,然后重新创建它及其属性(当然,以正确的顺序!),以便它们正常工作,并且不会抛出任何错误。

内联编写函数,解释器足够聪明,知道您正在编写函数。这样做,它假设它只是一个字符串(技术上是这样)。

function CheckBrowser(){
    if(navigator.userAgent.match(/Android/i)!=null||
        navigator.userAgent.match(/BlackBerry/i)!=null||
        navigator.userAgent.match(/iPhone|iPad|iPod/i)!=null||
        navigator.userAgent.match(/Nokia/i)!=null||
        navigator.userAgent.match(/Opera M/i)!=null||
        navigator.userAgent.match(/Chrome/i)!=null)
        {
            return 'OTHER';
    }else{
            return 'IE';
    }
}


function AddButt(i){
    var new_butt = document.createElement('input');
    new_butt.setAttribute('type','button');
    new_butt.setAttribute('value','Delete Item');
    new_butt.setAttribute('id', 'answer_del_'+i);
    if(CheckBrowser()=='IE'){
        new_butt.setAttribute("onclick", function() { DelElemAnswer(i) });
    }else{
        new_butt.setAttribute('onclick','javascript:DelElemAnswer('+i+');');
    }
}

你试过了吗:

    execBtn.setAttribute("onclick", function() { runCommand() });

在某些情况下,此处列出的示例在 Internet Explorer 中不适合我。

因为您必须使用这样的方法设置属性(不带括号)

HtmlElement.onclick = myMethod;

如果您必须传递对象名称甚至参数,它将不起作用。对于 Internet Explorer,您应该在运行时创建一个新对象:

HtmlElement.onclick = new Function('myMethod(' + someParameter + ')');

也适用于其他浏览器。

与 onclick 问题无关,但也相关:

对于名称与 javascript 保留字冲突的 html 属性,会选择一个备用名称,例如。 <div class=''>, , 但 div.className, , 或者 <label for='...'>, , 但 label.htmlFor.

在合理的浏览器中,这不会影响 setAttribute. 。所以在 gecko 和 webkit 中你会调用 div.setAttribute('class', 'foo'), ,但在 IE 中你必须使用 javascript 属性名称,所以 div.setAttribute('className', 'foo').

您是否考虑过使用事件侦听器而不是设置属性?除此之外,它还允许您传递参数,这是我在尝试执行此操作时遇到的一个问题。对于 IE 和 Mozilla,您仍然需要执行两次:

function makeEvent(element, callback, param, event) {
    function local() {
        return callback(param);
    }

    if (element.addEventListener) {
        //Mozilla
        element.addEventListener(event,local,false);
    } else if (element.attachEvent) {
        //IE
        element.attachEvent("on"+event,local);
    }
}

makeEvent(execBtn, alert, "hey buddy, what's up?", "click");

只需将事件命名为“单击”或“鼠标悬停”即可。

我这样做是为了绕过它并继续前进,在我的例子中,我没有使用“输入”元素,而是使用图像,当我尝试为此图像设置“onclick”属性时,我遇到了同样的问题,所以我尝试用“a”元素包装图像,并将引用指向像这样的函数。

var rowIndex = 1;
var linkDeleter = document.createElement('a');
linkDeleter.setAttribute('href', "javascript:function(" + rowIndex + ");");

var imgDeleter = document.createElement('img');
imgDeleter.setAttribute('alt', "Delete");
imgDeleter.setAttribute('src', "Imagenes/DeleteHS.png");
imgDeleter.setAttribute('border', "0");

linkDeleter.appendChild(imgDeleter);

尝试使用此ExecBtn.OnClick = function(){eval('runCommand()')};

对我来说它有效。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top