Don't know why I can't remove one div at a time

T

Terry

Hi again.

I am calling setTimeout like this:

function callLater(paramA)
{
return (function() {
paramA.style.display= "none";

});
}

function displaymenu(mealtype)
{
var i;
if(mealtype)
{
if (previous != "")
{
i =
document.getElementById(previous).getElementsByTagName('div').length-1;
while (i>=0)
{
var functRef =
callLater(document.getElementById(previous).getElementsByTagName('div')
);
setTimeout(functRef,i--,5000);



}

}
number =
document.getElementById(mealtype).getElementsByTagName('div').length;

for (i=0; i < number;i++)
document.getElementById(mealtype).getElementsByTagName('div')
.style.display= "block";
previous=mealtype;
}
}

Unfortunately, I do not see the divs being removed one at a time.
Instead they are removed all at the same time.

The url is http://restaurant.atwebpages.com/menu.htm

Thanks in advance,
Terry
 
D

David Golightly

Hi again.

I am calling setTimeout like this:

function callLater(paramA)
{
return (function() {
paramA.style.display= "none";

});

}

function displaymenu(mealtype)
{
var i;
if(mealtype)
{
if (previous != "")
Where does this come from? I suspect you don't need to use a global
variable here, either.
{
i =
document.getElementById(previous).getElementsByTagName('div').length-1;
while (i>=0)
{
var functRef =
callLater(document.getElementById(previous).getElementsByTagName('div')
);
setTimeout(functRef,i--,5000);


Same timeout interval: 5000. It should be something like 200*i.
}

}
number =

You should declare this variable with "var", or else you get an
implicit global.
document.getElementById(mealtype).getElementsByTagName('div').length;

for (i=0; i < number;i++)
document.getElementById(mealtype).getElementsByTagName('div')
.style.display= "block";


Here you really ought to cache this NodeList collection in a variable
outside the loop:

var divs =
document.getElementById(mealtype).getElementsByTagName('div');

Instead you call this same DOM operation in 4 separate places, all
without modifying the DOM. Call it once and be done with it!
Unfortunately, I do not see the divs being removed one at a time.
Instead they are removed all at the same time.

That is expected behavior. You're setting them all to be hidden in
5000 milliseconds, so they all get removed at the same time. If you
really want this effect, you should be incrementing the timeout
interval accordingly for each successive div.

-David
 
T

Terry

Same timeout interval: 5000. It should be something like 200*i.

I thought that by doing it the way that I was doing it that functref
is called every 5 seconds (that is, 5 seconds between iterations)
 
J

Jake Barnes

I thought that by doing it the way that I was doing it that functref
is called every 5 seconds (that is, 5 seconds between iterations)

Seems like you should be using setInterval, not setTimeout.
 
T

Terry

Seems like you should be using setInterval, not setTimeout.
What I am trying to do is have each div's display property set to
none. I would like the last div set to none after 1 second, and then
the next to last div set to none one second after that and so on. So I
think using setTimeout is fine.

Terry
 
J

Jake Barnes

while (i>=0)
{
var functRef =
callLater(document.getElementById(previous).getElementsByTagName('div')
);
setTimeout(functRef,i--,5000);

}

}



I don't think you understand what this while loop is doing. It is
looping through every div, all at once, and saying they should all
disappear in 5 seconds. So, yes, they all disappear at once, because
that is what your code says they should do.

What you want is a function that removes one div every 5 seconds. For
that you should use setInterval. Create a closure with the id (or
reference to) of the div you want to have disappear, and give that,
one at a time, to setInterval.

Another way to do it would be to keep the loop you have now, but
multiply i by 5000 and give that as the value to setTimeout. Thus you
would set the timeout of every div, but the value would go up as i
went up. You'd get the effect you want, if the effect you want is
purely visual.
 
R

Richard Cornford

Jake said:
while (i>=0)
{
var functRef =
callLater(document.getElementById(previous).
getElementsByTagName('div'));
setTimeout(functRef,i--,5000);

}

}



I don't think you understand what this while loop is doing.
It is looping through every div, all at once, and saying
they should all disappear in 5 seconds.


The second argument to the - setTimeout - function is the one that
provides the millisecond interval. Here that interval is not 5 seconds
but is instead - i-- -, which is going to be a variable value that gets
smaller as the loop goes on, but probably is never that large a value.
So, yes, they all disappear at once,

Or at least in such rapid succession that the result appears to be 'at
once'.
because
that is what your code says they should do.

What you want is a function that removes one div every 5
seconds. For that you should use setInterval. Create a
closure with the id (or reference to) of the div you want
to have disappear, and give that, one at a time, to
setInterval.
<snip>

If the closure has a reference to a single DIV element won't the result
of using it with - setInterval - be hiding the same element at 5 second
intervals?

Richard.
 
T

Terry

I don't think you understand what this while loop is doing. It is
looping through every div, all at once, and saying they should all
disappear in 5 seconds. So, yes, they all disappear at once, because
that is what your code says they should do.

What you want is a function that removes one div every 5 seconds. For
that you should use setInterval. Create a closure with the id (or
reference to) of the div you want to have disappear, and give that,
one at a time, to setInterval.

Another way to do it would be to keep the loop you have now, but
multiply i by 5000 and give that as the value to setTimeout. Thus you
would set the timeout of every div, but the value would go up as i
went up. You'd get the effect you want, if the effect you want is
purely visual.

Okay thanks, I changed

setTimeout(functRef,i--,4500)

to

setTimeout(functRef,500*i--);

and it worked.

I was surprised though to see that the link that I was clicking on
have its divs appear right away.

I guess I did not know how setTimeout would work either. I thought
that it would suspend everything until the functions that are called
within it were done their execution.

I was able to create the effect that I wanted suspending action on the
clicked link till the currently displayed links collapsing execution
has ceased by waiting for the same amount of time that it took for
that link's divs to collapse.

Thanks,
Terry
 
J

Jake Barnes

Jake said:
while (i>=0)
{
var functRef =
callLater(document.getElementById(previous).
getElementsByTagName('div'));
setTimeout(functRef,i--,5000);
}
}

I don't think you understand what this while loop is doing.
It is looping through every div, all at once, and saying
they should all disappear in 5 seconds.
What you want is a function that removes one div every 5
seconds. For that you should use setInterval. Create a
closure with the id (or reference to) of the div you want
to have disappear, and give that, one at a time, to
setInterval.

<snip>

If the closure has a reference to a single DIV element won't the result
of using it with - setInterval - be hiding the same element at 5 second
intervals?


Yes, true, unless you use a naming convention like:

var idOfDivToDisappear = "divToDisappear" +
variableThatGetsIncremented;

The variableThatGetsIncremented would have to be inside the enclosure.
It might initially have the value of i, but after that it would have
to increment itself. I mean, the code inside the enclosure would have
to increment it each time setInterval triggers the code in the
enclosure.

But, I now see that multiplying i by 5000 and giving that to
setTimeout is probably the simpler solution.
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]
glegroups.com>, Thu, 20 Sep 2007 23:29:38, Jake Barnes
Another way to do it would be to keep the loop you have now, but
multiply i by 5000 and give that as the value to setTimeout. Thus you
would set the timeout of every div, but the value would go up as i
went up. You'd get the effect you want, if the effect you want is
purely visual.

That creates multiple timers.

A more economical way is to set a timeout to call a function to close
the first div and set a timeout for the second div to ...

Untested code, to show idea :-

function ShutOne(N) { if (N<0) return
ShutDiv(N)
setTimeout("ShutOne(" + (N-1) + ")", 5000) }

setTimeout("ShutOne(6)", 5000)

It's a good idea to read the newsgroup c.l.j and its FAQ. See below.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top