By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,741 Members | 2,004 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,741 IT Pros & Developers. It's quick & easy.

Firefox2 problem with dynamic rendering (it's fine in IE, Safariand FF3)

P: n/a
I have a problem with Firefox 2 where if I resize the height of a DIV
(using JavaScript), but the rest of the page below isn't being updated
to reflect the new positions that affected items should be in. If I
(using the mouse) resize the browser slightly, then somehow FF2 realizes
things aren't in the right place and re-renders the page correctly. If I
were to have a JS function ( document.body.render(); ) available to me
for example, then I could manage this problem, but I don't. Or do I ?

I'm assuming there's a CSS property that can influence this behavior
somehow. Surely there must be, because *this simple test example below
is working just perfectly*. On the complex page I'm trying to implement
this on though, it doesn't work. The complex page has several CSS files
in it and I can't get any information from anyone knowledgeable about it
either. I've made this example below as minimalist as possible (removing
title, doctype and anything else I think is irrelevant to the example).
The only difference (in principle) between what I'm doing here (which
works) and what I'm doing on the complex page (which doesn't work) is
tons of CSS.

On the complex page, when you click on "200", then "div1" overlaps
"div2" until you resize the browser a little bit. And when you click on
"50", you see "div2" is left hanging further down until you resize the
browser a little.

<html><head>
<script>
function resizenow(x){
document.getElementById("div1_inner").style.height =x+"px";
}
</script>
</head><body>
<form>
<input type=button value="50" onclick="resizenow(50)">
<input type=button value="200" onclick="resizenow(200)">
</form>
<div id="div1" style="display:block;background-color:yellow;">
<div id="div1_inner" style="display:block;height:50px;">
<img width="100%" height="100%" src="" border="1">
</div>
</div>
<div id="div2">Something here</div>
</body></html>
Oct 3 '08 #1
Share this Question
Share on Google+
11 Replies


P: n/a
On Oct 3, 5:07*pm, Stevo <n...@mail.invalidwrote:
(...)

On the complex page, when you click on "200", then "div1" overlaps
"div2" until you resize the browser a little bit. And when you click on
"50", you see "div2" is left hanging further down until you resize the
browser a little.
try this:

function resizenow (x) {
var s= document.getElementById("div1_inner").style;
s.height= x+"px";
s.display= "none";
setTimeout(function () {
s.display= "";
},1);
};

--
Jorge.
Oct 3 '08 #2

P: n/a
Jorge wrote:
On Oct 3, 5:07 pm, Stevo <n...@mail.invalidwrote:
>(...)

On the complex page, when you click on "200", then "div1" overlaps
"div2" until you resize the browser a little bit. And when you click on
"50", you see "div2" is left hanging further down until you resize the
browser a little.

try this:

function resizenow (x) {
var s= document.getElementById("div1_inner").style;
s.height= x+"px";
s.display= "none";
setTimeout(function () {
s.display= "";
},1);
};
--
Jorge.
Thanks Jorge, I'll give that a try. It might produce an undesirable
flicker, but if it works, it at least might lead to another potential
solution. Perhaps I can add another 1 pixel high DIV in between div1 and
div2 and toggle that one's display property.
Oct 3 '08 #3

P: n/a
SAM
Le 10/3/08 7:03 PM, Stevo a écrit :
>
Thanks Jorge, I'll give that a try. It might produce an undesirable
flicker, but if it works, it at least might lead to another potential
solution. Perhaps I can add another 1 pixel high DIV in between div1 and
div2 and toggle that one's display property.

an other soluce could be :

function resizenow(x){
var d = document.getElementById("div1_inner");
var c = d.cloneNode(true);
c.style.height=x+"px";
d.parentNode.replaceChild(c,d);
}

Not tested.
Oct 3 '08 #4

P: n/a
On Oct 3, 9:34*pm, Jorge <jo...@jorgechamorro.comwrote:
On Oct 3, 5:07*pm, Stevo <n...@mail.invalidwrote:
(...)
On the complex page, when you click on "200", then "div1" overlaps
"div2" until you resize the browser a little bit. And when you click on
"50", you see "div2" is left hanging further down until you resize the
browser a little.

try this:

function resizenow (x) {
* var s= document.getElementById("div1_inner").style;
* s.height= x+"px";
* s.display= "none";
* setTimeout(function () {
* * * s.display= "";
* },1);

};
Though it might just work, can I ask the reasoning behind this
workaround? Is this is a known issue or does putting everything in
setTimeout always seems to solve the issue? ;-)
Oct 4 '08 #5

P: n/a
On Oct 3, 10:35*pm, SAM <stephanemoriaux.NoAd...@wanadoo.fr.invalid>
wrote:
Le 10/3/08 7:03 PM, Stevo a crit :
Thanks Jorge, I'll give that a try. It might produce an undesirable
flicker, but if it works, it at least might lead to another potential
solution. Perhaps I can add another 1 pixel high DIV in between div1 and
div2 and toggle that one's display property.

an other soluce could be :

function resizenow(x){
* *var d = document.getElementById("div1_inner");
* *var c = d.cloneNode(true);
* *c.style.height=x+"px";
* *d.parentNode.replaceChild(c,d);

}

Not tested.
This might just be a little too memory expensive operation since you
are creating a deep clone of the entire DIV tree; plus it is more work
for the GC since you always end up discarding the previous DOM node.

/sasuke
Oct 4 '08 #6

P: n/a
Jorge wrote:
On Oct 3, 5:07 pm, Stevo <n...@mail.invalidwrote:
>(...)

On the complex page, when you click on "200", then "div1" overlaps
"div2" until you resize the browser a little bit. And when you click on
"50", you see "div2" is left hanging further down until you resize the
browser a little.

try this:

function resizenow (x) {
var s= document.getElementById("div1_inner").style;
s.height= x+"px";
s.display= "none";
setTimeout(function () {
s.display= "";
},1);
};
--
Jorge.
I have this example working now thanks to your suggestion. I didn't
target the div1_inner for fear of seeing a flicker. Instead, I added a
brand new extra DIV which is 0 pixels high, and I toggle that. It has
the desired effect.

If anyone wants to experience this bizarre behavior in Firefox 2, save
this html in a file and try it. You can see how it works or doesn't
work, depending on whether the return statement is commented out in the
toggle function.

I know that if I were to change the CSS (somehow) then this behavior
would probably not be there, but I can't possibly change that. My only
power to change anything is by JavaScript, and even then, I'm limited.
If I were to change the CSS via JS, then there's a chance I would break
the page layout.

<html><head>
<style>
body{font:normal 12px arial,helvetica,sans-serif;position:relative;}
#div4{float:left;position:static;}
</style>
<script language="javascript">
function toggle()
{
return;
var x=document.getElementById('div3').style.display;
document.getElementById('div3').style.display=x==' none'?'':'none';
}
function resize50(x)
{
document.getElementById("div1_inner").style.height ="50px";
setTimeout(toggle,5);
}
function resize200(x)
{
document.getElementById("div1_inner").style.height ="200px";
setTimeout(toggle,5);
}
</script>
</head>
<body>
<form>
<input type=button value="50" onclick="resize50()">
<input type=button value="200" onclick="resize200()">
</form>
<div id="div1" style="display:block;background-color:yellow;width:200px;">
<div id="div1_inner" style="display:block;height:50px;width:200px;">
<img width="100%" height="100%" src="" border="1">
</div>
</div>
<div id="div2" style="display:block;background-color:red;width:200px;">
<div id="div2_inner" style="display:block;height:50px;width:200px;">
<img width="100%" height="100%" src="" border="1">
</div>
</div>
<div id="div3"
style="display:none;height:0px;line-height:0px;font-size:0px;">
</div>
<div id="div4">
<iframe width=100 height=100 frameborder=1 scrolling=yes></iframe>
</div>
</body>
</html>
Oct 4 '08 #7

P: n/a
On Oct 3, 9:34*pm, Jorge <jo...@jorgechamorro.comwrote:
On Oct 3, 5:07*pm, Stevo <n...@mail.invalidwrote:
(...)
On the complex page, when you click on "200", then "div1" overlaps
"div2" until you resize the browser a little bit. And when you click on
"50", you see "div2" is left hanging further down until you resize the
browser a little.

try this:

function resizenow (x) {
* var s= document.getElementById("div1_inner").style;
* s.height= x+"px";
* s.display= "none";
* setTimeout(function () {
* * * s.display= "";
* },1);

};
Is there any reasoning here for using `setTimeout' or is this a known
bug?
Oct 5 '08 #8

P: n/a
On Oct 3, 10:35*pm, SAM <stephanemoriaux.NoAd...@wanadoo.fr.invalid>
wrote:
Le 10/3/08 7:03 PM, Stevo a crit :
Thanks Jorge, I'll give that a try. It might produce an undesirable
flicker, but if it works, it at least might lead to another potential
solution. Perhaps I can add another 1 pixel high DIV in between div1 and
div2 and toggle that one's display property.

an other soluce could be :

function resizenow(x){
* *var d = document.getElementById("div1_inner");
* *var c = d.cloneNode(true);
* *c.style.height=x+"px";
* *d.parentNode.replaceChild(c,d);

}

Not tested.
IMO this approach might become a bit memory intensive considering that
you are creating a deep copy of the DIV element which might have a lot
many children element objects. Plus to end up discarding the previous
copy of the node means more work for the GC.

/sasuke
Oct 5 '08 #9

P: n/a
On Oct 4, 7:35*am, sasuke <database...@gmail.comwrote:
On Oct 3, 9:34*pm, Jorge <jo...@jorgechamorro.comwrote:
try this:
function resizenow (x) {
* var s= document.getElementById("div1_inner").style;
* s.height= x+"px";
* s.display= "none";
* setTimeout(function () {
* * * s.display= "";
* },1);
};

Though it might just work, can I ask the reasoning behind this
workaround? Is this is a known issue or does putting everything in
setTimeout always seems to solve the issue? ;-)
Hehe. What happens is that the the page isn't rendered until after the
JS code has finished executing (except in chrome). Therefore, a way to
force a redraw in the middle of some code, is to break it up in two
halves, let the first half end and schedule the second half to run
some ms later via a setTimeout().

--
Jorge.
Oct 5 '08 #10

P: n/a
On Oct 6, 12:16*am, Jorge <jo...@jorgechamorro.comwrote:
On Oct 4, 7:35*am, sasuke <database...@gmail.comwrote:
On Oct 3, 9:34*pm, Jorge <jo...@jorgechamorro.comwrote:
try this:
function resizenow (x) {
* var s= document.getElementById("div1_inner").style;
* s.height= x+"px";
* s.display= "none";
* setTimeout(function () {
* * * s.display= "";
* },1);
};
Though it might just work, can I ask the reasoning behind this
workaround? Is this is a known issue or does putting everything in
setTimeout always seems to solve the issue? ;-)

Hehe. What happens is that the the page isn't rendered until after the
JS code has finished executing (except in chrome). Therefore, a way to
force a redraw in the middle of some code, is to break it up in two
halves, let the first half end and schedule the second half to run
some ms later via a setTimeout().
Fair enough, but how does this scenario apply to the original post? In
the very first post, the function `resizenow(x)' exits soon after
setting the height to `x' pixels, so ideally the change should be
reflected immediately [and yes, it does, except in FF2]. So the only
reason here would be that the refresh isn't happening. So to trigger a
refresh, after setting the required dimensions, we hide and show the
DIV, with the only different thing being the showing of DIV be placed
in a `setTimeout'. Am I correct here?

/sasuke
Oct 6 '08 #11

P: n/a
On Oct 6, 6:14*pm, sasuke <database...@gmail.comwrote:
On Oct 6, 12:16*am, Jorge <jo...@jorgechamorro.comwrote:


On Oct 4, 7:35*am, sasuke <database...@gmail.comwrote:
On Oct 3, 9:34*pm, Jorge <jo...@jorgechamorro.comwrote:
try this:
function resizenow (x) {
* var s= document.getElementById("div1_inner").style;
* s.height= x+"px";
* s.display= "none";
* setTimeout(function () {
* * * s.display= "";
* },1);
};
Though it might just work, can I ask the reasoning behind this
workaround? Is this is a known issue or does putting everything in
setTimeout always seems to solve the issue? ;-)
Hehe. What happens is that the the page isn't rendered until after the
JS code has finished executing (except in chrome). Therefore, a way to
force a redraw in the middle of some code, is to break it up in two
halves, let the first half end and schedule the second half to run
some ms later via a setTimeout().

Fair enough, but how does this scenario apply to the original post? In
the very first post, the function `resizenow(x)' exits soon after
setting the height to `x' pixels, so ideally the change should be
reflected immediately [and yes, it does, except in FF2]. So the only
reason here would be that the refresh isn't happening. So to trigger a
refresh, after setting the required dimensions, we hide and show the
DIV, with the only different thing being the showing of DIV be placed
in a `setTimeout'. Am I correct here?
Yes, the div is hidden -JS code execution ends -a redraw takes
place -setTimeout times out and kicks in the code to show the div
again -code execution ends -another redraw cycle takes place...

--
Jorge.
Oct 6 '08 #12

This discussion thread is closed

Replies have been disabled for this discussion.