Log in

View Full Version : Switch Menu Function fails in IE



sniperman
11-20-2009, 02:20 PM
Hi, I am having trouble with a script that works fine in Firefox but has problems in IE. The offending piece of code is colored red. I know this is probably a simple case of "IE needs correct syntax" but need to polish up on my best practices.



window.onload = function initAll() {
// this function closes all the contained elements within the main content, on onload
var argument = document.getElementsByName("stories").length;
// loop through each element with an identical name attribute to store the instances
for (var i=0;i<argument;i++) {
document.getElementById('myvar'+[i+1]).style.display="none";
}
}


and this in the document body


<div name="stories" id="myvar1">
<p class="news">Headlines</p>

jscheuer1
11-20-2009, 04:46 PM
Nope, that line looks good. The problem is that the name attribute is non-standard for the div element. So, for example, say we do this:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript">
onload = function(){alert(document.getElementsByName('stories').length);};
</script>
</head>
<body>
<div name="stories" id="myvar1"></div>
</body>
</html>

Firefox alerts:


1

more or less as expected, but as mentioned above this is actually an error of sorts. IE 'gets it right' in this case, by ignoring the non-standard (technically invalid) name attribute, it alerts:


0

The name attribute is valid for these tags:


a
img
form
input
textarea
area (perhaps)


Maybe a few others. Generally, for what you are trying to do, class is used in conjunction with document.getElementsByClassName, but IE has no document.getElementsByClassName. So this (or something like it) is often done:


window.onload = function initAll() {
// this function closes all the contained elements within the main content, on onload
var argument = document.getElementsByTagName("div").length;
// loop through each element with an identical name attribute to store the instances
for (var i=0, c=0;i<argument;i++) {
if(argument[i].className === 'stories'){
document.getElementById('myvar'+[++c]).style.display="none";
}
}
};

with markup like:


<div class="stories" id="myvar1">
<p class="news">Headlines</p>

But this is less than ideal because an element may have more than one class. If you keep things simple though, it will be fine.

Speaking of simple though, consider the implications of this:


window.onload = function initAll() {
// this function closes all the contained elements within the main content, on onload
var argument = document.getElementsByTagName("div").length;
// loop through each element with an identical name attribute to store the instances
for (var i=0;i<argument;i++) {
if(argument[i].className === 'stories'){
argument[i].style.display="none";
}
}
};

A final note for now, although this construct:


window.onload = function initAll() {

is to be preferred for a number of reasons, it can cause problems in some cases, better to just do:


window.onload = function() {

Or even better as it incorporates the advatages without causing problems, define the initAll() function separately and invoke it directly:


function initAll(){
whatever;
}
onload = initAll;

sniperman
11-21-2009, 01:23 PM
thanks a lot for your input. it was very insightful.

For others who find this code useful however there was one typo. As long as the condition highlighted in red is closed the script works fine across browsers. much kudos.


window.onload = function initAll() {
// this function closes all the contained elements within the main content, on onload
var argument = document.getElementsByTagName("div").length;
// loop through each element with an identical name attribute to store the instances
for (var i=0;i<argument;i++) {
if(argument[i].className === 'stories'){
argument[i].style.display="none";
}
}
};

jscheuer1
11-21-2009, 02:12 PM
thanks a lot for your input. . . . there was one typo . . .


if(argument[i].className === 'stories')

You're welcome, and Good Catch on the typo! Now fixed in the original to avoid confusing others. I'm not sure how that happened, except I'm thinking this was a case where I never actually ran the code to test it.