views:

1509

answers:

5

I have a web page that uses a scrolling div to display table information. When the window is resized (and also on page load), the display is centered and the div's scrollbar positioned to the right of the page by setting its width. For some reason, the behaviour is different under firefox than IE. IE positions/sizes the div as expected, but firefox seems to make it too wide, such that the scrollbar begins to disappear when the window client width reaches about 800px. I'm using the following methods to set the position and size:

function getWindowWidth() {
  var windowWidth = 0;
  if (typeof(window.innerWidth) == 'number') {
    windowWidth=window.innerWidth;
  }
  else {
    if (document.documentElement && document.documentElement.clientWidth) {
      windowWidth=document.documentElement.clientWidth  ;
    }
    else {
      if (document.body && document.body.clientWidth) {
        windowWidth=document.body.clientWidth;
      }
    }
  }
  return windowWidth;
}

function findLPos(obj) { 
  var curleft = 0; 
  if (obj.offsetParent) { 
    curleft = obj.offsetLeft 
    while (obj = obj.offsetParent) { 
      curleft += obj.offsetLeft 
    } 
  } 
  return curleft; 
}

var bdydiv;
var coldiv;

document.body.style.overflow="hidden";
window.onload=resizeDivs;
window.onresize=resizeDivs; 

function resizeDivs(){
  bdydiv=document.getElementById('bdydiv');
  coldiv=document.getElementById('coldiv');
  var winWdth=getWindowWidth();
  var rghtMarg = 0;
  var colHdrTbl=document.getElementById('colHdrTbl');
  rghtMarg = parseInt((winWdth - 766) / 2) - 8;
  rghtMarg = (rghtMarg > 0 ? rghtMarg : 0);
  coldiv.style.paddingLeft = rghtMarg + "px";
  bdydiv.style.paddingLeft = rghtMarg + "px";
  var bdydivLft=findLPos(bdydiv);
  if ((winWdth - bdydivLft) >= 1){
    bdydiv.style.width = winWdth - bdydivLft;
    coldiv.style.width = bdydiv.style.width;
  }
  syncScroll();
}

function syncScroll(){
  if(coldiv.scrollLeft>=0){
    coldiv.scrollLeft=bdydiv.scrollLeft;
  }
}

Note that I've cut out other code which sets height, and other non-relevant parts. The full page can be seen here. If you go to the link in both IE and firefox, resize width until "800" is displayed in the green box top-right, and resize height until the scrollbar at the right is enabled, you can see the problem. If you then resize the IE width, the scrollbar stays, but if you resize the firefox width wider, the scrollbar begins to disappear. I'm at a loss as to why this is happening....

Note that AFAIK, getWindowWidth() should be cross-browser-compatible, but I'm not so sure about findLPos().... perhaps there's an extra object in Firefox's DOM or something, which is changing the result??

A: 

As long as you don't include a valid doctype, you can't expect consistent results, due to Quirks Mode. Go add one (HTML 4.01 Transitional is fine), then let us know if it still occurs.

Also see http://en.wikipedia.org/wiki/Quirks_mode.

Michael Madsen
Adding Transitional didn't change anything in either browser, unless I add "http://www.w3.org/TR/html4/loose.dtd" in which case I lose the div scrollbars altogether and end up with a page scrollbar (which I don't want)
Graza
The URL is required for Transitional to disable Quirks mode.If you get other issues from that, it suggests you're doing something else wrong (I'll need to take a closer look to see what's wrong, though). With Quirks Mode, IE will behave like IE5.5, and I'm sure you'll agree that's no good.
Michael Madsen
I agree in principle. Unfortunately though, this is a very large website with a lot of non-compliant HTML in it - I'm pretty sure we need quirks mode in this case. We are definitely doing things wrong in a lot of areas, but disabling quirksmode will mean a *huge* overhaul required...
Graza
A: 

In your getWindowWidth() function, whenever you grab the width of something, instead of this:

windowWidth = document.documentElement.clientWidth;

try this

windowWidth = Math.max(document.documentElement.scrollWidth, document.documentElement.clientWidth);
Bob Somers
This doesn't work - I need the actual *visible* width of the window to calculate where the div should be positioned/sized (and thus the scrollbar) - if I get the scrollable width, the scrollbar would be waaay of the screen....
Graza
A: 

A detail to help optimize some of your code:

function getPos(elm) {//jumper
    for(var zx=zy=0;elm!=null;zx+=elm.offsetLeft,zy+=elm.offsetTop,elm=elm.offsetParent);
    return {x:zx,y:zy}
}

(jumper is a user who posted this code in Eksperten.dk)

roenving
+1  A: 

Ok, I found the problem. Seems to be that firefox does not include the style.paddingLeft value in its style.width setting, whereas IE does, thus the div was ending up exactly style.paddingLeft too wide. That is, if for example style.paddingLeft is 8, IE's style.width value would be 8 more than FireFox's - and thus the inverse when setting the value, for FireFox I needed to subtract the style.paddingLeft value

Modified code with:

  if (__isFireFox){
    bdydiv.style.width = winWdth - bdydivLft - rghtMarg;
  } else {
    bdydiv.style.width = winWdth - bdydivLft;
  }
Graza
+2  A: 

You are dealing with "one of the best-known software bugs in a popular implementation of Cascading Style Sheets (CSS)" according to Wikipedia. I recommend the Element dimensions and CSS Object Model View pages on Quirksmode.org.

Also: I think you'll find that Safari and Opera behave like Firefox in most circumstances. A more compatible approach to working around these problems is testing for, and making exceptions for, MSIE instead of the other way around.

Borgar
Thanks for the extra info - it annoys me when I end up finding the solution to my own question and thus it remains "unanswered".... your post however is definitely the answer I was looking for. Wikipedia link was a perfect explanation :)
Graza
Glad I could help. :-)
Borgar