Results 1 to 6 of 6

Thread: Problem with resizing a div

  1. #1
    Join Date
    Nov 2006
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Problem with resizing a div

    I have a simple setup with two divs that are position:absolute. The first div is a header that I allow to expand to accomodate long topic titles or narrow browser windows that cause the text to wrap. The second div is the content, which scrolls beneath the header. When the header resizes, the content div must be repositioned so the top is below the header. In IE6 I also have to reset the height of the content div, or the vertical scroll bar extends below the bottom of the window. Here is my script as it currently stands:

    Code:
    <script type="text/javascript">
    window.onload = adjustContent;
    window.onresize = adjustContent;
    
    var DHTML = (document.getElementById || document.all);
    
    function adjustContent() {
      if (!DHTML) return;
    
      var oHeader = new getObj('FPheader');
      var oContent = new getObj('FPcontent');
    
      oContent.style.top = oHeader.obj.offsetHeight + "px";
      oContent.style.height = document.body.offsetHeight - oHeader.obj.offsetHeight;
    }
    
    function getObj(name){
      if (document.getElementById){
        this.obj = document.getElementById(name);
        this.style = document.getElementById(name).style;
      }
      else if (document.all){
        this.obj = document.all[name];
        this.style = document.all[name].style;
      }
    }
    </script>
    This script works perfectly in Netscape 7-8, Opera 8-9, Firefox 2, and IE6. Which is kind of amazing, because document.body.offsetHeight is 0 to all the browsers except IE6, so the script is attempting to set a negative style.height. Without the '+"px"' addition to the header height, the script will not work in Netscape7-8 or Firefox. Opera and IE6 don't care.

    This morning I installed IE7, and things went bad fast. It doesn't like the "px", and it doesn't like the negative height. It's also showing a double vertical scroll bar, suggesting that it wants a width set, but the scroll bar is the right height, unlike IE6.

    Is there any possible way I can fix this script so that it will work without browser sniffing? It seems so elegant the way it is, if I can just figure out what to use in place of the body's offsetHeight and what to do about the "px" problem. It is essential that it work in IE6-7, since it's a template for an HTML help project, but I would like it to be fully cross-browser compatible if possible so the project could be exported as a Web site.

    Thanks in advance.

    Brett

  2. #2
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Instead of document.body.offsetHeight, try adding this function to your page:

    Code:
    function iecompattest(){
    return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body;
    }
    So that it is available to all other functions. The same with this one:

    Code:
    function get_win_h(){
    return window.innerHeight? window.innerheight : iecompatest().clientHeight? iecompatest().clientHeight : 0;
    }
    Now, wherever you use:

    Code:
    get_win_h()
    It will return the window (inner) height dimension or 0 if it cannot determine it, ex:

    Code:
    oContent.style.height = get_win_h() - oHeader.obj.offsetHeight +'px';
    I'm not entirely clear if this will help but, it certainly will if you are trying to reposition and/or resize on the basis of the window's height.

    One thing to also be aware of, pixel units should always be used for style.height and style.top unless you want to use other units (like em's or pt's or %), in which case you should specify them. Except in NN4, which this script would never work in to begin with. You will also probably get more consistent results if you use a Strict or Transitional DOCTYPE.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  3. #3
    Join Date
    Nov 2006
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Thanks, John. After much study of tutorials on heights and widths, plus much head banging, I finally came up with this script, which does the trick:

    Code:
    window.onload = adjustContent;
    window.onresize = adjustContent;
    
    // Be sure we're working under DOM.
    
    var DHTML = (document.getElementById || document.all);
    
    function adjustContent(){
    	if (!DHTML) return;
    
    	var oHeader = new getObj('FPheader');
    	var oContent = new getObj('FPcontent');
    
    	// Move the top of the content area for all browsers.
    
    	oContent.style.top = parseInt(oHeader.obj.offsetHeight,10) + 'px';
    
    	// For IE browsers (which don't recognize window.innerWidth/Height), we
    	// have to adjust the height of the content area or the scroll bar will
    	// extend below the window.  We also need to adjust the width to keep
    	// the scroll bar in the right place.
    
    	if (!window.innerWidth){
    		var oWinSize = getWinSize();
    
    		oContent.style.overflow = 'auto';
    		oContent.style.height = oWinSize.height - parseInt(oHeader.obj.offsetHeight,10);
    
    		oContent.style.width = oWinSize.width;  // Quirks mode
    
    		if (document.documentElement && document.documentElement.clientWidth){  // Standards mode
    			oContent.style.width = oWinSize.width - getExcessWidth(oContent);
    		}
    	}
    }
    
    // Create an object to reference a div element.
    
    function getObj(name){
    	if (document.getElementById){
    		this.obj = document.getElementById(name);
    		this.style = document.getElementById(name).style;
    	}
    	else if (document.all){
    		this.obj = document.all[name];
    		this.style = document.all[name].style;
    	}
    }
    
    // Determine the height and width of the viewport.
    
    function getWinSize(){
    	var iWidth = 0, iHeight = 0;
    
    	if (document.documentElement && document.documentElement.clientHeight){
    		iWidth = parseInt(document.documentElement.offsetWidth,10);
    		iHeight = parseInt(document.documentElement.offsetHeight,10);
    	}
    	else if (document.body){
    		iWidth = parseInt(document.body.offsetWidth,10);
    		iHeight = parseInt(document.body.offsetHeight,10);
    	}
    
    	return {width:iWidth, height:iHeight};
    }
    
    // Total up any border and padding applied to the right and left sides of the content division.
    // These must be removed from the window offsetWidth to set the style.width for the content
    // division in IE.  Note that borders and padding *must* be specified in pixels for this to
    // work properly.
    
    function getExcessWidth(oContent){
    	var iExcess = 0;
    
    	if (window.getComputedStyle) {
    		iExcess = parseInt('0' + window.getComputedStyle(oContent.obj, null).getPropertyValue("padding-left"),10) +
    		          parseInt('0' + window.getComputedStyle(oContent.obj, null).getPropertyValue("padding-right"),10) +
    		          parseInt('0' + window.getComputedStyle(oContent.obj, null).getPropertyValue("border-left"),10) +
    		          parseInt('0' + window.getComputedStyle(oContent.obj, null).getPropertyValue("border-right"),10);
    	}
    	else if (oContent.obj.currentStyle) {
    		iExcess = parseInt('0' + oContent.obj.currentStyle.paddingLeft,10) +
    		          parseInt('0' + oContent.obj.currentStyle.paddingLeft,10) +
                  parseInt('0' + oContent.obj.currentStyle.borderLeft,10) +
                  parseInt('0' + oContent.obj.currentStyle.borderRight,10);
    	}
    
    	return (iExcess);
    }
    (Not quite as simple as the original, eh? But, things never are.)

    I solved the 'px' problem by doing a parseInt on the header height before adding the 'px' back on. Now FF and IE7 are both happy.

    The double-scrollbar problem in IE7 was handled by putting scroll="no" in the body tag to get rid of the main scrollbar, and then deducting any left/right border or padding from the offsetWidth. Unfortunately, that means I have to specify the padding in pixels instead of ems, since IE7 returns the original em units instead of converting them to pixels like the other browsers.

    I also ended up needing another script from AListApart to detect font-size changes, so the content could resize properly in response to those as well as to window resizing.

    But, it all works now, in all the browsers I've got. I sure have wasted a lot of time on what is really just a minor effect!

  4. #4
    Join Date
    Nov 2006
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Hi BrettM,

    I was just wondering how does the parseInt() help if the value is negative. I am a beginner JS programmer and having the same problem too(IE6 -> IE7) and I was considering something like

    if (ht <0) {
    ht = -ht;
    }

    Is there a more elegant solution ?

  5. #5
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Math.abs(number)

    will return the absolute value of the number.
    Last edited by jscheuer1; 11-15-2006 at 04:45 AM.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  6. #6
    Join Date
    Jan 2007
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    I'm having a similar issue getting DIVs automatically adjust their size. Do you have an example page of the project you were working on?

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •