Forum Moderators: open

Message Too Old, No Replies

Length of page in Netscape 7

(rather than browser window height)

         

ga_ga

10:13 pm on Jun 5, 2004 (gmt 0)

10+ Year Member



I'm successfully using the following javascript in IE6 to find the height of a document (top to bottom, including the scrollable height):

return (document.body.scrollHeight > document.body.clientHeight)?
document.body.scrollHeight : document.body.clientHeight;

Can someone briefly explain this code (from a syntax point of view - having trouble following what it's saying), and suggest similar properties I could use in Netscape 7 to find the full length of a page at any given browser size and aspect? (i.e. return more or less the same as the code above, except in Netscape..)

thanks

ga_ga

11:01 pm on Jun 5, 2004 (gmt 0)

10+ Year Member



(I'm trying to use document.height in Netscape 7.1, without success - always get the same value regardless of how I have the browser sized & the content flowed)

- hang on.. beginning to look like some of my other CSS is causing something to go wrong here. I de-linked the style sheet & document.height has started returning sensible numbers. Hmm...

Bernard Marx

12:46 am on Jun 6, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Can someone briefly explain this code (from a syntax point of view...

It's a 'terniary' [takes three operands] conditional operator. A kind of shortcut.
It's good for assignment, and

[blue]return[/blue]
statements.

variable = (anything that can have a boolean value)? true_value : false_value

Imagine you had this:

[blue]var theColour = [/blue]
..thatDepends..

You want to assign something to

[blue]theColour[/blue]
, depending on some condition.
So you go:

[blue]var theColour = (season=="summer")? "blue" : "green";
[/blue]

You don't actually need the
[blue]()[/blue]
. It just helps.
You can also format it how you like.
The long way round would be:

[blue]if(season=="summer")
var theColour = "blue"
else
var theColour = "green"[/blue]

If you want to nest, you simply replace one of the values with another set:

[blue]var theColor = (season=="summer")? "blue" 
: (happy)? "green" :"brown"[/blue]

So, if it's not Summer, but you're happy, it's green.

Oh yes, sorry I forgot. The statement you quoted has a condition that evaluates to true if

[blue]scrollHeight > clientHeight[/blue]
.
So it effectively will return the larger of the two (clientheight, if both the same). In fact, it would be easier to do:

[blue]return Math.max(document.body.scrollHeight,document.body.clientHeight)[/blue]

ga_ga

1:58 am on Jun 6, 2004 (gmt 0)

10+ Year Member



Thanks for the explanation Bernard :-)

so.. a function I just wrote containing

.
.
else if (sniffer says netscape)
{
HTMLOVERFLOW = (document.height > innerHeight)? 1 : 0;
return (HTMLOVERFLOW == 1)? document.height : innerHeight;
}
.
.

should set global flag HTMLOVERFLOW to 1 if the page is taller than the viewing area, or 0 if the content fits within it without scrolling.. and return the height of the viewing area, or the height of the document itself, whichever is bigger?

unfortunately something seems amiss. The IE equivalent works fine for positioning an image permanently at the base of the window/document, but I can't seem to get Netscape to play ball unless I unlink my stylesheet.

Maybe I should have done with it & go back to putting the whole page in tables :-(

Bernard Marx

10:58 am on Jun 6, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



As far as pure JS goes, Yes. I thought for a minute that you hadn't got it, but then I realised you wanted to set a global flag, in which case it's as concise as any I can think of. Maybe I'd change the last bit to this, for the hell of it:

[blue]return (HTMLOVERFLOW)? document.height : innerHeight; [/blue]

You may have noticed that I've avoided any mention of the key DHTML issue. To be honest that one scares me right now. For a fully cross-browser technique, there are so many issues to deal with {browser, OS, quirks¦¦standards mode}. Sometimes the body can have a different height to the document. Does one get the dimensions from the

[blue]document.body[/blue]
or the
[blue]document.documentElement[/blue]
? How does one reliably get the window's inner dims to compare this with?

The IE equivalent works fine for positioning an image permanently at the base of the window/document

Confused << (..a little). If you want something permanently positioned relative to the window, standards browsers have been supporting CSS

[blue]position:fixed[/blue]
for a while now. So you could do:

#theImage
{
position:[blue]fixed[/blue];
left: 0px;
bottom: 0px;
..etc..
}

If I understand the problem, that might well sort you out in all browsers from the standards / Mozilla camp, keeping your image at the bottom-left corner of the window, even after scrolling - and without using Javascript.

IE won't like it. It treats

[blue]fixed[/blue]
as
[blue]static[/blue]
. So for them, you override the
[blue]fixed[/blue]
in a stylesheet (onpage or linked) within a conditional comment:

<!--[if IE]>
<style>
#theImage{ position:[blue]absolute[/blue]; }
</style>
<![endif]-->

Then you do your Javascript magic on the image position, but only having to worry about doing it in IE.

Although I have done things like this, I haven't tested this particular solution. So I can't guarantee its reliability, or be held responsible when it drives you nuts.

Conditional comments: [msdn.microsoft.com ]
PPK on viewport dims: [quirksmode.org ]

This could be done without JS, using "CSS frame emulation" (sorry, no good links handy).

Rambo Tribble

2:02 pm on Jun 6, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Does this help?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Faking a float</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<style type="text/css">
html,body{height:100%;}
#main{overflow:scroll;font:4em Verdana,sans-serif;}
#botDiv{position:absolute;bottom:0;height:120px;width:100%;background:red;}
</style>
<script type="text/javascript">
function setHt(){
var oh=document.getElementById("pgBod").offsetHeight;
var nh=oh-120;
document.getElementById("main").style.height=nh+"px";
}
</script>
</head>
<body id="pgBod" onload="setHt();">
<div id="main">Textual material, ad infinitum. Textual material, ad infinitum. Textual material, ad infinitum.
Textual material, ad infinitum. Textual material, ad infinitum. Textual material, ad infinitum.
</div>
<div id="botDiv">
</div>
</body>
</html>

By the way, your!DOCTYPE declaration should control the rendering mode, vis-a-vis "quirks".

ga_ga

4:12 pm on Jun 6, 2004 (gmt 0)

10+ Year Member



bottom: would have been good but I can't use it for the case where I want to deal with the position at the bottom of the content, rather than the bottom of the window.

Using this code, I can get what I'm trying to do to work cross-browser by the simple expedient of only doing it in IE.. good enough for now, while I read over the posts again a few times & experiment some more to try and do something for netscape & opera.

<script language="JavaScript" type="text/javascript">
<!--

// Sniff for IE4 & up

function ClientObject() {
var agt = navigator.userAgent.toLowerCase();
var is_major = parseInt(navigator.appVersion);
var is_minor = parseFloat(navigator.appVersion);
this.ie = ((agt.indexOf('msie')!= -1) && (agt.indexOf('opera') == -1));
this.ie4up = (this.ie && (is_major >= 4));
}

var is = new ClientObject();

// If so, add scaling image footer to bottom of page.
// If not IE4+, leave things well alone..

// footer is a rolling hills graphic, with sky the same color
// as the page background so it merges in.

if (is.ie4up)
{

HTMLOVERFLOW = ((document.body.scrollHeight + document.body.clientHeight/4) > document.body.clientHeight)? 1 : 0;
pageBaseHeight = (HTMLOVERFLOW == 1)? document.body.scrollHeight : document.body.clientHeight;

document.write("<img id='footer' src='image.gif' width='100%' height='25%' style='position:absolute; top:0px; left:0%;'>");

if (HTMLOVERFLOW == 1)
{
// Not enough space to shoehorn the footer graphic in,
// without scrollbars, and without obscuring text.
// Just tack the footer graphic to the bottom.
// Scrollbar gets a little longer, that's all.
footer.style.top=pageBaseHeight;
}
else
{
// There's enough vertical space to add in the footer graphic,
// without causing scrollbars & without obscuring text.
// Add in the graphic at the correct height above the window's base:
footer.style.top=(pageBaseHeight-(document.body.clientHeight/4)+4);
document.body.style.overflow="hidden";
}
}
-->
</script>

Rambo Tribble

10:27 pm on Jun 6, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Maybe I don't understand your description, but why can't you just place the content in one div and the footer in a following div?

Bernard Marx

11:14 pm on Jun 6, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



My interpretation is that we want to only display the footer when there's enough room [?]
I'm with Tribble. The footer can be just be at the bottom. However, I don't reckon you need the content wrapped in a DIV. That may be the best solution though, if this is going to go cross-browser.
Ironically, my demo consists of 2 DIVs.
1. "stuff" - represents the document content. It's only a single DIV to make it easy for me. The dims are read from the document.body.

2. "footer" - represents the image. It is set to display:none until page load. I think it's unfair on a browser to ask its body dims before all HTML has loaded. So the element isn't written by write().

This may require some "magic" numbers for best performance, and it's only tested IE.
[ ... who knows what will happen if you add a strict docType ]

<html><head><title>Space Check</title>
<script>

window.onload = function()
{
checkSpace()
}

function checkSpace()
{
var db = document.body
var footer = document.getElementById("footer")
footer.style.display =
(
db.clientHeight
> db.scrollHeight
+ parseInt(footer.style.height)
)
? "block":"none";
}

[red]// --demo only-- //[/red]
function footerHeight(select)
{
var height = select.options[select.selectedIndex].value + "px"
document.getElementById("stuff").style.height = height
checkSpace()
}
[red]// -- // -- //[/red]
</script>
</head>
<body>

[red]<!-- demo only -->[/red]
<div style="position:absolute;left:600px;top:50px;">
<select onchange = "footerHeight(this)" >
<option value="300">300
<option value="500">500
<option value="600">600
</select>
</div>[red]<!--//-->[/red]

<div id = "stuff"
style="width:300;height:300px;background-color:#92EFC7;"></div>

<div id="footer"
style="display:none;width:100%;height:200px;background-color:#DFEFA5;">
</body>
</html>

ga_ga

12:55 am on Jun 7, 2004 (gmt 0)

10+ Year Member



Thanks - having a good play about with that. Different approach looks promising!

Bernard Marx

1:23 am on Jun 7, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hmm. I've just spotted a logical inconsistency when checking height.
When checking, if the 'footer' is already displayed, then the footer height needs to be taken out of the condition - or it's counted twice.


function checkSpace()
{
var db = document.body
var footerStyle = document.getElementById("footer").style
var addFootHeight = (footerStyle.display=="none")
? parseInt(footerStyle.height)
: 0;

footerStyle.display = (db.clientHeight > db.scrollHeight + addFootHeight)
? "block":"none";
}

..or maybe I should just get some sleep!