473,395 Members | 2,798 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

FireFox/IE behavior diff during onload

KPS
I'm attempting to create a simple treeview-like behavior in JavaScript.
The desired behavior happens in IE but I cannot get the same to happen
in FireFox.

The primary thing I want to accomplish is to set the id and href of
some objects dynamically during the onload of the page instead of
hard-coding it in the HTML. I want to set the id/href so when I add new
entries I don't have to remember to increment the id's.

In FireFox, the href of the oAnchor and the id's for the oImage and
oList objects never get set (but the id for the oSpan object does).

Here is the code:

<head>
<style>
ul {
list-style : none;
}
a {
text-decoration : none;
}
img {
border-style : none;
margin: 0px 5px 1px 0px;
}
..closed ul {
display : none;
}
</style>
<script language="JavaScript" type="text/javascript">
function toggle(id) {
var oSpan = document.getElementById(id);
var oImage = document.getElementById("img" + id);
var oList = document.getElementById("list" + id);

if (oSpan.className == 'closed') {
oSpan.className = 'open';
oImage.src = "minus.gif";
oList.style.display = 'block';
}
else {
oSpan.className = 'closed';
oImage.src = "plus.gif";
oList.style.display = 'none';
document.getElementById("expandAll").checked = false;
}
}
function expandAll() {
var classname = "open";

if (document.getElementById("expandAll").checked) {
classname = "closed";
}

var oSpan = document.getElementsByTagName("span");
for (var i=0; i<oSpan.length; i++) {
if (oSpan[i].className == classname) {
toggle(oSpan[i].id);
}
}
}
onload = function() {
var classname = "closed"
var oSpan = document.getElementsByTagName("span");
for (var i=0; i<oSpan.length; i++) {
if (oSpan[i].className == classname) {
oSpan[i].id = i;
var oAnchor = oSpan[i].firstChild;
oAnchor.href = "javascript:toggle(" + i + ")"
var oImage = oAnchor.firstChild;
oImage.id = "img" + i;
var oList = oSpan[i].lastChild;
oList.id = "list" + i;
}
}
}
</script>
</head>

<table>
<tr>
<td>
<input type="checkbox" id="expandAll" onclick="expandAll();"
/>Expand All
</td>
</tr>
<tr>
<td>
<ul>
<li>
<span class="closed">
<a><img src="plus.gif" />TEST</a>
<ul>
<li><a href="http://www.google.com"><img src="square.gif"
/>FOO</a></li>
<li><a href="http://www.google.com"><img src="square.gif"
/>BAR</a></li>
</ul>
</span>
</li>
</ul>
</td>
</tr>
</table>

Mar 15 '06 #1
1 2440
KPS said on 15/03/2006 10:03 AM AEST:
I'm attempting to create a simple treeview-like behavior in JavaScript.
The desired behavior happens in IE but I cannot get the same to happen
in FireFox.
Because of how you are trying to reference elements, see below.

The primary thing I want to accomplish is to set the id and href of
some objects dynamically during the onload of the page instead of
hard-coding it in the HTML. I want to set the id/href so when I add new
entries I don't have to remember to increment the id's.
You don't have to create IDs for them anyway, what's the point? You
don't seem to use them for anything.

In FireFox, the href of the oAnchor and the id's for the oImage and
oList objects never get set (but the id for the oSpan object does).
The reason is that the DOM tree is not as you expect - use the DOM
Inspector. Firefox (and other Gecko-based browsers) insert #text nodes
in the DOM to preserve whitespace in the source HTML. It is these nodes
that are messing with your firstChild/lastChild references.

Here is the code:

<head>
<style>
A type attribute is required.

<style type="text/css">

ul {
list-style : none;
}
a {
text-decoration : none;
}
img {
border-style : none;
margin: 0px 5px 1px 0px;
}
.closed ul {
display : none;
}
</style>
<script language="JavaScript" type="text/javascript">
The language attribute is deprecated, drop it and keep type.

function toggle(id) {
var oSpan = document.getElementById(id);
var oImage = document.getElementById("img" + id);
var oList = document.getElementById("list" + id);

if (oSpan.className == 'closed') {
oSpan.className = 'open';
oImage.src = "minus.gif";
oList.style.display = 'block';
Do you really want 'block' or just not 'none'? You can set it to ''
(empty string) if you like to get the default style.

Since you change the class of the outer SPAN, there is no need to set
the display property of the UL anyway, you've already done that with CSS
(just remove the oList.style.display lines here and below and it's done).

}
else {
oSpan.className = 'closed';
oImage.src = "plus.gif";
oList.style.display = 'none';
document.getElementById("expandAll").checked = false;
}
}
function expandAll() {
var classname = "open";

if (document.getElementById("expandAll").checked) {
classname = "closed";
}

var oSpan = document.getElementsByTagName("span");
Rather than sift through all the span elements in the entire document,
get a reference to some element that is an ancestor of all the spans you
want, then use its getElementsByTagName() method. You should get a much
smaller list of spans.

for (var i=0; i<oSpan.length; i++) {
if (oSpan[i].className == classname) {
And if you add a second class to any of the elements? Maybe you never
will, but it's safer to use say:

var classRE = new RegExp('\\b' + classname + '\\b');
var span;
for (var i=0, len=oSpan.length; i<len; i++){
span = oSpan[i];
if (span.className && classRE.test(oSpan[i].classname){

toggle(oSpan[i].id);
}
}
}
onload = function() {
var classname = "closed"
var oSpan = document.getElementsByTagName("span");
for (var i=0; i<oSpan.length; i++) {
if (oSpan[i].className == classname) {
See above.

oSpan[i].id = i;
Setting an element's id to a number is not valid HTML (though most
browsers will tolerate it). An id can contain numbers, it just can't
start with a number.

var oAnchor = oSpan[i].firstChild;
You need to be careful here. *Any* whitespace between the SPAN and A
tags in the source HTML will introduce a #text node as the first child
of the SPAN in Gecko browsers (e.g. Firefox). IE does not do that, it
removes such whitespace completely.

oAnchor.href = "javascript:toggle(" + i + ")"
Do not use javascript in the href attribute, it causes unwanted
behaviour. Use an onclick attribute instead (or don't use an A element
at all)

var oImage = oAnchor.firstChild;
Given that there is no whitespace between your A and IMG tags, this
should work but you likely oAnchor is not a reference to the A element
that you expect.

oImage.id = "img" + i;
Here you will get an error message in the JavaScript console:

oImage has no properties
Which is because a #text node doesn't have an id attribute.

var oList = oSpan[i].lastChild;
Since there is whitespace after the closing UL tag, Gecko browsers will
add a #text node, so that is what oList will refer to.
oList.id = "list" + i;
a #text node can't have an ID attribute[1], the DOM object referenced by
oList may be assigned an id, but I'm not sure it will do you any good.

}
}
}
</script>
</head>

<table>
<tr>
<td>
<input type="checkbox" id="expandAll" onclick="expandAll();"
/>Expand All
Is this really XHTML? If not, don't use '/>' to close the tags of empty
elements.

</td>
</tr>
<tr>
<td>
<ul>
<li>
<span class="closed">
Use the DOM Inspector, you'll see a #text node here.
<a><img src="plus.gif" />TEST</a>
And here.

<ul>
And here.

<li><a href="http://www.google.com"><img src="square.gif"
/>FOO</a></li>
And here, etc.
<li><a href="http://www.google.com"><img src="square.gif"
/>BAR</a></li>
</ul>
</span>
</li>
</ul>
</td>
</tr>
</table>


The trivial solution is to remove the whitespace between the opening
SPAN tag and the first A tag, and between the closing UL and SPAN tags.
But I think you can do better. Consider this simpler version:

<style type="text/css">
.closed ul { display : none; }
.open ul { display :list-item ;}
</style>

<script type="text/javascript">
function toggleClass(el)
{
el.className = (el.className == 'open')?'closed':'open';
}
</script>

<ul>
<li class="closed" onclick="toggleClass(this);"><a><img
src="plus.gif">TEST</a>
<ul>
<li><a href="http://www.google.com"><img
src="square.gif">FOO</a></li>
<li><a href="http://www.google.com"><img
src="square.gif">BAR</a></li>
</ul>
</li>
</ul>
<ul>
<li class="closed" onclick="toggleClass(this);"><a><img
src="plus.gif">TEST</a>
<ul>
<li><a href="http://www.google.com"><img
src="square.gif">FOO</a></li>
<li><a href="http://www.google.com"><img
src="square.gif">BAR</a></li>
</ul>
</li>
</ul>

1. #text nodes have no attributes, just a value which is the
content and one splitText method from DOM interface Text.

<URL:http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1312295772>
--
Rob
Mar 15 '06 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Johnny | last post by:
Searched on google for any info relating to this before posting here but found none. I set up a web service using nusoap on apache php 4.3.8 on windows with error_reporting = E_ALL and had that...
6
by: R. Rajesh Jeba Anbiah | last post by:
In IE, I could be able to directly refer the "id", but it isn't possible in Firefox. Somewhere I read the solution is to refer the id like document.getElementById("month") in Firefox. If I do so,...
13
by: Giggle Girl | last post by:
Hi there, I am having a problem with the behavior of Firefox, where lefthand column content is not resized properly after it is "collapsed" and then "re-expanded". An online demo is available...
1
by: gatejs | last post by:
In IE. If you use the back button, the resulting page will execute the javascript in the page again: In Firefox, whatever value a variable had is kept when you go back to it: var i=0; //...
3
by: jon | last post by:
Hello, I've had long standing code that runs in IE, that I'm testing with firefox unsuccessfully now. The problem seems to be that images that I dynamically create don't fire their onload event...
4
by: puja | last post by:
hi all, I have an asp.net website where am including .css file dynamically on page load event. For diff users, there is diff CSS file. So after user logs in, I am setting CSS href on page load....
22
by: giordan | last post by:
Hi all! I've wrote this code: <script type="text/javascript"> var largImg; var altImg; var txtTop = '<b>Ottima scelta!</b> Ora compila il form e premi "Ricevi banner". Il...
3
by: willyWEB66 | last post by:
Hi everyone, I'm having problem with the sequence of execution for xml.onload. It works fine if your not passing parameters to onload event but my code needs to pass parameter to its function. I'm...
1
by: SunshineInTheRain | last post by:
My project has 3 files, File1 has included master page. file1 consists of iframe1 that load file2. File2 consists of iframe2 that load file3. Javascript used on each file to resize the iframe...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.