I have a control contained in an iframe on a page of my ASP.NET web application.
Control changes its vertical size correspondingly to what user selects on it (some elements get in, others get out). So, I have to set the iframe size precisely to get the whole control shown and not to make gap between the iframe and the elements below it.
Somewhere on the web I have found a way to get the document height in a cross-browser way:
function getDocHeight(document) {
return Math.max(
Math.max(document.body.scrollHeight, document.documentElement.scrollHeight),
Math.max(document.body.offsetHeight, document.documentElement.offsetHeight),
Math.max(document.body.clientHeight, document.documentElement.clientHeight)
);
}
On self.document.body.onload on the control page, hence, I call this function:
function adjustIframeHeight() {
var iframe = window.parent.document.getElementById(window.frameElement.id);
var iframeHeight = getDocHeight(iframe.contentWindow.document);
iframe.style.height = iframeHeight + "px";
}
The problem is it works fine e.g. in Firefox, but in some cases bottom sections of the control are cutoff in Chrome and IE for example.
Is there some truly cross-browser way to get this height, or I am doing something else wrong?
Thank you for the time
I'd use something like jQuery to help out with this (since using height methods seem to vary from browser to browser) and here is some jQuery code that could help out:
$(document).height(); // height of HTML doc
Related
Note that I'm not asking how to make a div the size of the "window" or "viewport" for which there are plenty of existing questions.
I have a web page of some height and width, and I'd like to add an empty, top-level div (i.e., not one containing the rest of the page) with a size exactly equal to the page's height and width. In practice, I also want it to be at least the size of the viewport.
I know I can do a one-time calculation of the height and width in JavaScript:
var height = Math.max(document.body.scrollHeight,
document.documentElement.clientHeight);
var width = Math.max(document.body.scrollWidth,
document.documentElement.clientWidth);
But this value can change based on images loading, or AJAX, or whatever other dynamic stuff is going on in the page. I'd like some way of locking the size of the div at the full page size so it resizes dynamically and on-demand.
I have tried something like the following:
function resetFakeBg() {
// Need to reset the fake background to notice if the page shrank.
fakeBg.style.height = 0;
fakeBg.style.width = 0;
// Get the full page size.
var pageHeight = Math.max(document.body.scrollHeight,
document.documentElement.clientHeight);
var pageWidth = Math.max(document.body.scrollWidth,
document.documentElement.clientWidth);
// Reset the fake background to the full page size.
fakeBg.style.height = pageHeight + 'px';
fakeBg.style.width = pageWidth + 'px';
}
// Create the fake background element.
fakeBg = setFakeBgStyle(document.createElement('div'));
document.body.appendChild(fakeBg);
// Keep resizing the fake background every second.
size_checker_interval = setInterval(resetFakeBg, 1000);
Limitations
This is for a Chrome extension, and I'd like to limit my modification of the page to adding this single div. This means that adding CSS to modify the height and width of the html and/or body tags is undesirable because it might have side-effects on the way the rest of the page is rendered.
In addition, I do not want to wrap the existing page in the div because that has the potential to break some websites. Imagine, for example, a site styled with the CSS selector body > div. I'd like my extension to break as few websites as possible.
WHY OH WHY WOULD I NEED TO DO THIS?
Because some people like to hold their answers hostage until they're satisfied that I have a Really Good Reason™ for wanting to do this:
This is for an accessibility-focused Chrome extension that applies a CSS filter across an entire page. Recent versions of Chrome (>= 45) do not apply CSS filters to backgrounds specified on the <html> or <body> tag. As a result, I have chosen to work around this limitation by copying the page's background onto a div with a very negative z-index value, so that it can be affected by the page-wide CSS filter. For this strategy to work, the div needs to exactly imitate the way the page background would appear to a user—by being the exact size of the document (and no larger) and at least filling the viewport.
setInterval() is your best friend in cases like this where you want the .height() and .width() of an element to be asynchronously specified all the time to something that can be dynamicly altered by user input and DOM tree changes. It is what I dub as a "page sniffer", and arguably, works better than $(document).ready if you are working in multiple languages (PHP, XML, JavaScript).
Working Example
You should get away with setting the width and height in the window resize function, you might wanna add it in a load function as well, when all data/images are loaded.
just add width=100%
e.g;-
Hello World
I think you must do it like this:
...
<body>
<script>
function height()
{var height = Math.max(document.body.scrollHeight,
document.documentElement.clientHeight);}
function width()
{var width = Math.max(document.body.scrollWidth,
document.documentElement.clientWidth);}
</script>
<div height="height()" width="width()">
</div>
</body>
...
Here's a couple of ways to ask this question:
How can I get the height (in pixels) at which the page will start having scroll bars? In other words, how do i get the window height at which a scroll bar will appear?
How can I get the maximum height of all elements on the page that don't have relative
heights (e.g. height: 100%)?
This question is related, but the answer doesn't do what I want in the case of relative heights: Finding the full height of the content of a page/document that can have absolutely positioned elements
I made a js fiddle of what I'm talking about: http://tinyurl.com/kgf8dae . Unfortunately, jsfiddle seems to break the relative height put on div e - run it as an html page in a normal browser to see the real behavior.
I might be misunderstand the question. In general, if the window height is less than the document height you will get a vertical scrollbar.
So in jQuery the check might look like this:
if( $(document).height() > $(window).height() ){ /* There will be a scrollbar */ }
You can perform this check within DOM changing and window resizing events to ascertain if a scrollbar has appeared. To preemptively determine if an event would cause a scrollbar to appear can be tricky and would likely require some understanding of the page and potential events to handle efficiently.
This is tagged through jQuery so I'm going to use jQuery; even though it's not mentioned in the question body.
a) It sounds like you want to get the height of the viewport (window); which can be retrieved like this:
var height = $(window).height();
If the height of the document (page) exceeds the height of the window, and there are no CSS properties blocking the display of scrollbars, then scrollbars will indeed by visible.
if( $(document).height() > $(window).height() )
b) This is going to be a bit trickier, in the sense the only way off the top of my head is to query every DOM element.. this is not a elegant solution; and in fact I'd ask you to reconsider your approach if you really you must do this. That said.. for curiosity...
If you're looking for the max height, in the sense of the largest element - then this would work:
// Get height of largest element.
var max_height = 0;
$('*').each( function(){
// skip <html> and <body>
if( ( $(this).get(0) == $('body').get(0) ) || ( $(this).get(0) == $('html').get(0) ) )
return;
var current_height = $(this).height();
if( current_height > max_height )
max_height = current_height;
});
For example, running that on this page...
> console.log( max_height );
570
However, I'm not sure if you want the maximum height of all combined elements.. In which case we obviously need to add all the elements up, but there's the obvious problem: elements are nested!
If this is what you want, then by using .children() we can just iterate through the lengths of the elements that are immediate children of your containing element/body.
// Get height of all combined elements
var combined_height = 0;
$('body').each( function(){ // replace with containing element?
combined_height = combined_height + jQuery(this).height();
});
For example, running that on this page:
> console.log(combined_height);
2176
Using the HTML/CSS from the example your provided via (jsfiddle.net/RMe3n/1). The answer is and always will be 242.
However, I assume you're looking for a more dynamic approach. Running the following after DOM ready will also produce 242:
var answer = 0;
$('#absolutes > div').each(function(){
var h = $(this).outerHeight(true);
if(answer < h) answer = h;
})
alert(answer);
While the above will solve for the particular HTML/CSS you provided it makes a lot of assumptions about the page's HTML structure and CSS.
Is it possible that the problem you are attempting to address with JS could be resolved in a "cleaner" way by adjusting the HTML/CSS of your page?
If you are looking for a fool proof JS method to account for ALL the multitude of unique layouts/styles that exist now and may exist as more CSS3 display types are adopted in the future I believe you're out of luck. There is no recommendable, consistent, efficient way to do so.
Note: If this is more than just a theoretical discussion, consider being more specific about the exact scenario you are faced with as there is likely a vastly different approach that may resolve the issue.
I have a page that I need to dynamically load ajax content when the user scrolls to the bottom. The problem is that JQuery is not returning the correct window height. I have used this function before and have never seen it fail, but for some reason it will return the same value as the document height. I have the test page here: bangstyle.com/test-images
I have coded the alert to display at page load, and also whenever the user scrolls 500px below the top:
function scroller() {
if($(window).scrollTop() > 500){
delay(function(){ //200ms wait
pagecounter++;
sideshow();
alert("window height: " + $(window).height() + " scrolltop: " + $(window).scrollTop() + " document height: " + $(document).height());
return false;
}, 200 );
}
}
I tried posting this before but I deleted it as I didn't get a solution. I hope it is ok to post a link to my test page. BTW I have tested this on Mac Safari and Mac FF. I have run this same code on other pages and it works fine. I feel there must be something in the dom of this page that causes JS to fail, but no idea what that would be.
Look at your HTML souce code.
The first line should be <!DOCTYPE html> and you have <style> tag instead.
So it seems that your document is running in Quirks Mode and jQuery can't calculate correct window dimensions.
//works in chrome
$(window).bind('scroll', function(ev){
//get the viewport height. i.e. this is the viewable browser window height
var clientHeight = document.body.clientHeight,
//height of the window/document. $(window).height() and $(document).height() also return this value.
windowHeight = $(this).outerHeight(),
//current top position of the window scroll. Seems this *only* works when bound inside of a scoll event.
scrollY = $(this).scrollTop();
if( windowHeight - clientHeight === scrollY ){
console.log('bottom');
}
});
I had the same problem.
I've found some things:
1) the problem happens when you try to get the actual height before document is completed rendered;
2) the problem happens in google chrome when you does not use corret DOCTYPE (mentioned above)
3) it always happens in google chrome even after the document is rendered completly.
For google chrome, I've found a workaround here: get-document-height-cross-browser
I'm using this solution only for google chrome and it resolved my problem, I expect helps someone that still have the problem.
This is an old question but I recently struggled with not getting the correct window height in IE10 by a few pixels.
I discovered that IE10 applies a 75% zoom by default and that screws the window and document measurements.
So, if you're getting wrong width or height, make sure zoom is set to 100%.
Did some looking around and stumbled upon this, don't know if it helps but it's worth bringing up.
why is $(window).height() so wrong?
Since jquery (and dom in general) is not calculating sizes correctly in quirksmode, two solutions:
Add doctype html at the top of your page (like mentioned in "correct" answer), or
Use window.innerHeight, window.innerWidth if first option is not an option.
Hope it helps.
I moved my scripts from to footer and that resolved it for me.
How do I go about getting what the height of an element on a page would be if it ignored the 'height' css property applied to it?
The site I'm working on is http://www.wncba.co.uk/results and the actual script I've got so far is:
jQuery(document).ready(function($) {
document.origContentHeight = $("#auto-resize").outerHeight(true);
refreshContentSize(); //run initially
$(window).resize(function() { //run whenever window size changes
refreshContentSize();
});
});
function refreshContentSize()
{
var startPos = $("#auto-resize").position();
var topHeight = startPos.top;
var footerHeight = $("#footer").outerHeight(true);
var viewportHeight = $(window).height();
var spaceForContent = viewportHeight - footerHeight - topHeight;
if (spaceForContent <= document.origContentHeight)
{
var newHeight = document.origContentHeight;
}
else
{
var newHeight = spaceForContent;
}
$("#auto-resize").css('height', newHeight);
return;
}
[ http://www.wncba.co.uk/results/javascript/fill-page.js ]
What I'm trying to do is get the main page content to stretch to fill the window so that the green lines always flow all the way down the page and the 'Valid HTML5' and 'Designed By' messages are never above the bottom of the window. I don't want the footer to stick to the bottom. I just want it to stay there instead of moving up the page if there's not enough content to fill above to fill it. It also must adapt itself accordingly if the browser window size changes.
The script I've got so far works but there's a small issue that I want to fix with it. At the moment if the content on the page changes dynamically (resulting in the page becoming longer or shorter) the script won't detect this. The variable document.origContentHeight will remain set as the old height.
Is there a way of detecting the height of an element (e.g. #auto-resize in the example) and whether or not it has changed ignoring the height that has been set for it in css? I would then use this to update the variable document.origContentHeight and re-run the script.
Thanks.
I don't think there is a way to detect when an element size changed except using a plugin,
$(element).resize(function() //only works when element = window
but why don't you call refreshContentSize function on page changes dynamically?
Look at this jsFiddle DEMO, you will understand what I mean.
Or you can use Jquery-resize-plugin.
I've got it working. I had to rethink it a bit. The solution is on the live site.
The one think I'd like to change if possible is the
setInterval('refreshContentSize()', 500); // in case content size changes
Is there a way of detecting that the table row has changed size without chacking every 500ms. I tried (#content).resize(function() but couldn't to get it to work.
I'm measuring the window and document width and height via the following properties :
//measure the window and document height and width dynamically
var w = $(window).width();
var h = $(window).height();
var wd = $(document).width();
var hd = $(document).height();
Works fine in firefox but IE kicks up a fuss. Is there an alternative to this syntax that works in IE?
JS error recieved - could not get the position property. Invalid Argument
Works for me in both FF and IE, check for yourself here.
i just figured out, whats the "bug" in the code.
Firefox is able to get width and height, whereever you put your javascript.
But IE is only able to get this values when the script is within the body element.
I've had the same problem here and was trying about an hour.
I noticed, that the jsbin script is inside the pagebody and moved my javascript into the body and wow - it works in IE :-)
Best regards
I had the same problem and i solve it.
The question was related with IE being in Quircks mode, because i had in the begining of the HTML some non valid tags (i copy the source from a .aspx page, and i left there the <%page ..%> directive.
When IE finds some strange tag it enters quircks mode, and some things work diferent.
When i deleted the strange tag, the $(window).width(); stuff begins to work.
Hope this helps someone in the future with my same problem. :)