Why does an onclick property set with setAttribute

2019-01-03 05:40发布

Ran into this problem today, posting in case someone else has the same issue.

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

Turns out to get IE to run an onclick on a dynamically generated element, we can't use setAttribute. Instead, we need to set the onclick property on the object with an anonymous function wrapping the code we want to run.

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

BAD IDEAS:

You can do

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

but it will break in IE in non-standards mode according to @scunliffe.

You can't do this at all

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

because it executes immediately, and sets the result of runCommand() to be the onClick attribute value, nor can you do

execBtn.setAttribute("onclick", runCommand);

14条回答
做个烂人
2楼-- · 2019-01-03 06:26

Write the function inline, and the interpreter is smart enough to know you're writing a function. Do it like this, and it assumes it's just a string (which it technically is).

查看更多
走好不送
3楼-- · 2019-01-03 06:27

to make this work in both FF and IE you must write both ways:


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

thanks to this post.

UPDATE: This is to demonstrate that sometimes it is necessary to use setAttribute! This method works if you need to take the original onclick attribute from the HTML and add it to the onclick event, so that it doesn't get overridden:

// 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
}
查看更多
女痞
4楼-- · 2019-01-03 06:28

There is a LARGE collection of attributes you can't set in IE using .setAttribute() which includes every inline event handler.

See here for details:

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

查看更多
SAY GOODBYE
5楼-- · 2019-01-03 06:31

In some cases the examples listed here didn't work out for me in Internet Explorer.

Since you have to set the property with a method like this (without brackets)

HtmlElement.onclick = myMethod;

it won't work if you have to pass an object-name or even parameters. For the Internet Explorer you should create a new object in runtime:

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

Works also on other browsers.

查看更多
成全新的幸福
6楼-- · 2019-01-03 06:31

Not relevant to the onclick issue, but also related:

For html attributes whose name collide with javascript reserved words, an alternate name is chosen, eg. <div class=''>, but div.className, or <label for='...'>, but label.htmlFor.

In reasonable browsers, this doesn't affect setAttribute. So in gecko and webkit you'd call div.setAttribute('class', 'foo'), but in IE you have to use the javascript property name instead, so div.setAttribute('className', 'foo').

查看更多
疯言疯语
7楼-- · 2019-01-03 06:32

works great!

using both ways seem to be unnecessary now:

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

apparently works in every current browser.

tested in current Firefox, IE, Safari, Opera, Chrome on Windows; Firefox and Epiphany on Ubuntu; not tested on Mac or mobile systems.

  • Craig: I'd try "document.getElementById(ID).type='password';
  • Has anyone checked the "AddEventListener" approach with different engines?
查看更多
登录 后发表回答