setAttribute doesn't work in IE6
how to set element attribute with javascript in IE6..? It seems setAttribute
doesn't work. I really need to do it on the fly. Thanks.
Code
<script type="text/javascript" language=开发者_高级运维"javascript">
menuItems = document.getElementById("menu").childNodes;
for (i = 0; i < menuItems.length; i++)
{
if (menuItems[i].className != "blue")
menuItems[i].setAttribute('onmouseover', 'HoverMenu(this)');
}
</script>
(Most of the below was before the OP clarified they were setting an event handler; left the list of other issues in case others find them useful)
IE6 makes a mess of several aspects of setAttribute
. Without knowing the exact problem you were dealing with (this was before the edit inidicating it was an event handler), it's hard to be sure whether that's really the problem, but here are a couple of known issues:
You can't use setAttribute
to set event handlers
It's best to set event handlers using the reflected property or with addEventListener
[standard] / attachEvent
[IE], not setAttribute
(and you can't use setAttribute
on IE).
So, any of these will work:
// Using reflected property
theElement.onclick = yourFunction;
// Using DOM2 standard addEventListener; note it's "click", not "onclick"
theElement.addEventListener("click", yourFunction, false);
// IE's non-standard alternative to addEventListener
theElement.attachEvent("onclick", yourFunction);
...not
// This doesn't work on IE (at least)
theElement.setAttribute("onclick", "yourFunction();");
The addEventListener
/ attachEvent
way of doing this is cool for other reasons: You can have multiple event listeners on the same event of an element. You can't do that using the reflected property.
So for your specific situation:
menuItems = document.getElementById("menu").childNodes;
for (i = 0; i < menuItems.length; i++)
{
if (menuItems[i].className != "blue") {
menuItems[i].onmouseover = function() {
HoverMenu(this);
}
}
}
Certain attributes need their modified names
class
The correct way to set the class attribute is to use the reflected property className
:
// Correct, cross-browser way. Works on IE6+, all versions of
// Chrome, etc. Completely reliable.
theElement.className = "new set of classes";
or on modern browsers (so, not IE6!) you can use classList
.
One of IE6's many setAttribute
bugs is that this doesn't work:
// Should also work, but fails on IE6 (and probably some other old versions)
theElement.setAttribute("class", "new set of classes");
Instead, IE6 (and probably a couple of other versions) make you use "className"
instead of "class"
, even though that makes no sense whatsoever. The reflected property has the name className
because it used to be that in JavaScript, you couldn't use reserved words (like class
or for
or if
) as property literals (obj.class
was invalid). That's not been true for a while now (ECMAScript 5 fixed it), but that's why the reflected property is className
, not class.
But since setAttribute
takes a string, it should accept the proper name of the attribute. The fact it doesn't is just an IE bug (and one they've fixed in modern versions of IE if they're not in [in]compatibility mode).
for
Similarly, to set the for
attribute (for instance, on label
s), one uses the htmlFor
reflected property:
// Correct, cross-browser way. Works on IE6+, all versions of
// Chrome, etc. Completely reliable.
theLabel.htmlFor = "id-of-field";
On any non-broken browser, you can also use setAttribute
:
// Should also work, but fails on IE6 (and probably some other old versions)
theLabel.setAttribute("for", "id-of-field");
...but not on IE6, it wants "htmlFor"
instead of "for"
for the same reason it wants "className"
rather than "class"
(e.g, because it's broken).
This page has quite a list of attributes that are problematic with IE.
setAttribute
can't be used to set the style
attribute
...you have to use the style
property instead; but to be fair, that's usually a more convenient way. Example: This won't work on IE:
theElement.setAttribute("style", "color: blue"); // Doesn't work on IE
...but this will:
myElement.style.color = "blue";
Slightly OT: Look at libraries
JavaScript libraries like Prototype, jQuery, Closure, or any of several others will make most of the above a lot easier and smooth out differences amongst browsers if you go through their APIs.
I would really look at jquery. It has all the functionality that works with IE6 and this would be so much easier than the code you have here. It would look like this:
menuItems = $("#menu")[0].childNodes;
$.each(menuItems, function()
{
var item = $(this);
if (item.attr("className") != "blue")
item.mouseover(HoverMenu);
}
This code might need to be tweaked a little as I am just writing from memory.
I say easier because what you are trying to do in setting events like this varies based on browser and can be a headache to setup. But with jquery it is all done for you.
精彩评论