473,242 Members | 1,726 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,242 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 2435
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: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...

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.