Forum Moderators: open

Message Too Old, No Replies

Why is this so?

What is firefox giving a different answer?

         

crookyboy

5:47 pm on Aug 25, 2005 (gmt 0)

10+ Year Member



Can someone please explain to me why this code:

<div id="test">
<p>This is a sample paragraph.</p>
</div>

<script>
alert(document.getElementById("test").childNodes.length);
</script>

gives "1" in IE (which is what you would expect)

but gives "3" in Firefox?

Bernard Marx

6:02 pm on Aug 25, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There are empty text nodes before and after the P. Try with the HTML written on a single line.
It's always best to test for such nodes when DOM-navigating.

crookyboy

6:08 pm on Aug 25, 2005 (gmt 0)

10+ Year Member



OK Cheers,

So why wont this work:

<style>
#n1 p
{
display:none;
}
</style>

<div id="n1"><p>AAAAAA</p><p>BBBBBB</p><p>CCCCCC</p><p>DDDDDD</p><p>EEEEEE</p></div>

<script>
document.getElementById("n1").childNodes[1].childNodes[0].setAttribute("display:block");
</script>

should make BBBBBB display on page

garann

8:09 pm on Aug 25, 2005 (gmt 0)

10+ Year Member



Maybe setAttribute isn't working at runtime? Does it work if you say
document.getElementById("n1").childNodes[1].childNodes[0].style.display="block";
?

crookyboy

9:16 pm on Aug 25, 2005 (gmt 0)

10+ Year Member



no, it doesn't.

But it should. Why can't firefox just support "document.getElementById(id).children" - that would make my life easier.

garann

10:02 pm on Aug 25, 2005 (gmt 0)

10+ Year Member



Ooh! What if you get rid of that second
.childNodes[0]
? It would appear you're trying to set the style of the first child of
n1
's second child. And that second paragraph doesn't have any children. I know I've had this work in FF. There has to be a way...

crookyboy

10:18 pm on Aug 25, 2005 (gmt 0)

10+ Year Member



no, doesn't work either.

crookyboy

10:25 pm on Aug 25, 2005 (gmt 0)

10+ Year Member



This is my code, see if you can get it to work in firefox cos i sure as hell cant.

<html>
<head>
<script type="text/javascript">
function run(count)
{
var list = document.getElementById("ticker").childNodes;
if(list[count-1])
{
list[count-1].style.display = "none";
list[count-1].setAttribute("display:none");
}
else
{
list[list.length-1].style.display = "none";
list[list.length-1].setAttribute("display:none");
}
list[count].style.display = "block";
list[count].setAttribute("display:block");
count++;
if(count == list.length)
count = 0;
window.setTimeout("run(" + count+ ")",5000);
}
</script>
</head>
<body>
<div id="ticker"><h3>This is an H3 element</h3><p>Test 1 - this is my first sentance, isn't it a great sentance, it can be as long as you want it to be har har</p><p>Test 2 - this is my second sentance</p><p>Test 3 - this is my third sentance</p></div>
<script type='text/javascript'>
run(0);
</script>
</body>
</html>

garann

10:45 pm on Aug 25, 2005 (gmt 0)

10+ Year Member



Well, you're right, I can't get your code to work - but FF is having a problem with references to array elements that don't exist (
list[count-1]
when count is 0), not with the childNodes property. What are you trying to do there?

crookyboy

11:11 pm on Aug 25, 2005 (gmt 0)

10+ Year Member



well the function is recursive, that turns off the last element if it exists - that can't be the problem because i do:

if(list[count-1])

the condition checks if the array element exists. If it doesn't exist (quite right, when count is 0), it will simply return false.

So that can't be the problem firefox has. It's just bad implementation of the DOM - there are loads of articles on its bad implementation - but noone seems to have found a fix.

crookyboy

11:19 pm on Aug 25, 2005 (gmt 0)

10+ Year Member



fixed it with this code:

<html>
<head>
<script type="text/javascript">
function run(count)
{
var list = document.getElementById("ticker").childNodes;
if(count > 0)
{
list[count-1].style.display = "none";
}
else
{
list[list.length-1].style.display = "none";
}
list[count].style.display = "block";
count++;
if(count == list.length)
count = 0;
window.setTimeout("run(" + count+ ")",1000);
}
</script>
<style type="text/css">
#ticker h3, #ticker p
{
display:none;
}
</style>
</head>
<body>
<div id="ticker"><h3>This is an H3 element, it should still work!</h3><p>Test 1 - this is my first sentance, isn't it a great sentance, it can be as long as you want it to be har har</p><p>Test 2 - this is my second sentance</p><p>Test 3 - this is my third sentance</p></div>
<script type='text/javascript'>
run(0);
</script>
</body>
</html>

It seems checking if an array element exists (that doesn't exist) causes firefox to die.

Oh well, you learn something every day i guess.

garann

11:23 pm on Aug 25, 2005 (gmt 0)

10+ Year Member



<edit>Nevermind, I see you got there on your own.</edit>

that can't be the problem because i do:

if(list[count-1])

the condition checks if the array element exists

That so? :) That statement is causing your script to break in FF. Have you used the FF Javascript console? You can see the error there.

If you replace that test with something less dangerous, like

if(count>0)
, and get rid of the setAttribute lines, I think you'll find your code works pretty well after all.

crookyboy

11:37 pm on Aug 25, 2005 (gmt 0)

10+ Year Member



Thanks for your help anyway.

I also wrote this "pre-render" function which strips whitespace elements from the DOM tree that firefox produces:


function initialiseList(divId)
{
list = document.getElementById(divId).childNodes;
for (var i=0; i<list.length; i++)
{
var node = list[i];
if (node.nodeType == 3 &&!/\S/.test(node.nodeValue))
document.getElementById(divId).removeChild(node);

}
run(divId, 0);
}