I tried:
$(document).height();
$("#body").height();
but it make doesn't give an exact value.
You are looking for the scroll height property
var el = document.body;
console.log(el.scrollHeight); // height with overflow
body {
height: 100vh;
}
.div {
height: 10000px;
}
<div class="div">
</div>
Check out the specs for the height function:
// Returns height of browser viewport
$( window ).height();
// Returns height of HTML document
$( document ).height();
The "height of the overall page" I interpret to be the size of the viewport. If you're looking for something a little more robust...
function getPageHeight ()
{
//If the content is smaller than the viewport, return the height
//of the screen. Otherwise, return the height of the content.
return Math.max ($(window).height (), $('body').height ());
}
Related
I have 2 divs, a navigation and a main content in a bootstrap grid system. The length of either can vary depending on amount of content. I need them both styled to fill 100% of the browser window IF neither has the content to reach the bottom naturally. But if at least one of the divs has more content than the length of the browser window, I need to be able to scroll down the page with the styles of both divs remaining in tact and both have a height of the longer of the 2 divs.
I'm currently using a javascript resize function which seems to work but not in the case where neither div is long enough to fill the height of the browser window. Any suggestions?
HTML
<div class="row">
<div id="nav" class="col-xs-2">
Variable Height Navigation
</div>
<div id="main" class="col-xs-10">
Variable Height Content
</div>
</div>
Javascript
function resize() {
var h = (document.height !== undefined) ? document.height : document.body.offsetHeight;
document.getElementById("nav").style.height = h + "px";
}
resize();
window.onresize = function () {
resize();
};
I am trying to understand you question, and if I'm correct what you are looking for is:
Both divs need to be equally high
They need be at least the height of the screen
They need to take the height of the highest div
So let's try to achieve this goal as simply as possible:
var main = document.getElementById('main');
var nav = document.getElementById('nav');
function resize(){
var highest;
// Set the divs back to autosize, so we can measure their content height correctly.
main.style.height = 'auto';
nav.style.height = 'auto';
// Find the highest div and store its height.
highest = main.clientHeight > nav.clientHeight
? main.clientHeight
: nav.clientHeight;
// Check if the highest value is the div or the window.
highest = highest > window.innerHeight
? highest
: window.innerHeight;
// Assign the newly found value
main.style.height = highest + 'px';
nav.style.height = highest + 'px';
}
resize();
// Also, you don't need to wrap it in a function.
window.resize = resize;
// However, better would be:
window.addEventListener('resize', resize, false);
#main, #nav {
width: 100%;
height: auto;
}
#main { background: red; }
#nav { background: green; }
<div id="main"></div>
<div id="nav"></div>
Now, If you aren't bothered with the actual sameness in heiught of both divs but just want them to at least be one screenful, you should consider using CSS:
html, body { height: 100%; }
#nav, #main { min-height: 100%; }
I think that is the better solution (no Javascript!) and sort-of does what you want, bar the fact that you won't have to equally high div elements. However, you would barely notice it as each will at least fill the page.
You could try using viewport height:
For example:
#nav {
min-height: 100vh;
}
#main {
min-height: 100vh;
}
See Bootply.
This will also remove the need for JavaScript.
I want to have a div be fixed at the bottom of the window when the window is taller than the content height. If the content height is taller than the window height, I want the div position to remain relative.
I currently have this mostly working, however I don't want the div to overlap the content at all. I tried various forms of below, but still not working:
var body = content+bottomBar
if (body > viewport) {
$(".bottom-bar").css({
'position':'relative'
});
} else {
$(".bottom-bar").css({
'position': 'fixed'
})
}
I also am having trouble getting the window.resize to work.
Any help would be appreciated!
http://jsfiddle.net/no05x1vx/1/
Referring to the jsfiddle linked by the OP, here are a few changes to make the code work as expected, please see the comments:
var content = $(".content").height()
var viewport = $(window).height();
// Use innerHeight here as the bottom-bar div has height 0 and padding 60px
// .height() would return 0
var bottomBar = $(".bottom-bar").innerHeight();
var body = parseInt(content)+parseInt(bottomBar)
$(window).on('resize', function(){
// Get new viewport height
viewport = $(window).height();
if (content > (viewport-bottomBar) ) {
$(".bottom-bar").css({
'position':'relative'
});
} else {
$(".bottom-bar").css({
'position': 'fixed'
})
}
});
// Trigger resize after page load (to avoid repeated code)
$(document).ready(function(){
$(window).resize();
});
This question already has an answer here:
jQuery window.scroll move div vertical in opposite direction
(1 answer)
Closed 7 years ago.
How can I reverse the scroll function of my website such that when the user scrolls up, the page will scroll down in the opposite direction?
Doing this for the entire page is going to give a very broken experience.
You'll wind up doing something like the following, where you find the height of your content, then start manually positioning it within a fixed viewport:
var $window = $(window), $container, height;
$(function() {
$container = $('#content');
// Add some content
for (var i = 0; i < 1000; ++i) {
$container.append('<h1>line ' + i + '</h1>');
}
height = $container.outerHeight();
$('body').css('height', height + 'px');
// Set up scroll handling, but also invoke once to initialize positions
$window.on('scroll', onScroll);
onScroll();
});
function onScroll() {
scrollTop = $window.scrollTop();
$container.css('top', (scrollTop - height + $window.height()) + "px");
}
#content {
position: absolute;
}
#viewport {
position: fixed;
width: 100%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="viewport">
<div id="content">
</div>
</div>
Basically, #viewport remains fixed infront of the user, occupying the whole screen. The content scrolls backwards inside of #viewport while the HTML document scrolls normally.
Meanwhile, #content has a height of ~50,000px, which I read and apply directly to the document, so that there will be a scroll bar of the appropriate size even though #content is contained within #viewport which has a fixed height set to that of the window.
Then, on scroll, the actual content gets position so that it moves upwards by the same distance you've scrolled with scrollTop.
Situation:
I'm working on a responsive design that involves the typical HTML/CSS combo. Everything is working nicely except in one case where there is an iframe inside of a div. The iframe should adjust automatically to the size of the parent div. A purely css solution has not presented itself so I'm going with a JQuery approach. It works nicely except in one scenario, when resizing from a smaller width to a larger width screen.
HTML:
<div class="container">
<iframe class="iframe-class" src="http://www.cnn.com/"></iframe>
</div>
CSS:
.container {
width: 100%;
height: 250px;
}
.iframe-class {
width: 100%;
height: 100%;
border: 1px solid red;
overflow: auto;
}
Javascript:
$(function () {
setIFrameSize();
$(window).resize(function () {
setIFrameSize();
});
});
function setIFrameSize() {
var ogWidth = 700;
var ogHeight = 600;
var ogRatio = ogWidth / ogHeight;
var windowWidth = $(window).width();
if (windowWidth < 480) {
var parentDivWidth = $(".iframe-class").parent().width();
var newHeight = (parentDivWidth / ogRatio);
$(".iframe-class").addClass("iframe-class-resize");
$(".iframe-class-resize").css("width", parentDivWidth);
$(".iframe-class-resize").css("height", newHeight);
} else {
// $(".iframe-class-resize").removeAttr("width");
// $(".iframe-class-resize").removeAttr("height");
$(".iframe-class").removeClass("iframe-class-resize");
}
}
http://jsfiddle.net/TBJ83/
Problem:
As the window is resized smaller, it continually checks the window width and once it hits < 480 px, the code adds a class called iframe-class-resize and sets the width and height to that class. As the window is resized larger, it removes the class once the size hits 480 px. The problem is that setting the width and height attributes adds them directly to the element and not the class itself. Therefore, removing the class does not remove the new width and heights. I tried to force removing the attributes using removeAttr() (commented out above) but that didn't work.
Anyone see where the code above went wrong? Or any suggestions on how to accomplish having a responsive iframe more effectively? The main things that are required are that the iframe has to be inside the <div></div> and the div may not necessarily have a width or height defined. Ideally, the parent div should have the width and height explicitly defined but the way this site is currently setup, that won't always be possible.
Additional:
In case the above wasn't clear enough, try the following to reproduce the issue:
Open up a browser on a desktop machine. I'm using Chrome on a Windows machine. Don't maximize the browser.
Open up the jsfiddle above (http://jsfiddle.net/TBJ83/). You'll notice that the iframe content spans the entire width of the Preview panel.
Manually resize the width down until the entire window is < 480px. At this point, the iframe content will be pretty tiny.
Manually resize the width back up until the entire window is >> 480px. The goal is to have that iframe content to regain the entire width of the Preview panel. Instead, the content is retaining the resized width and height since the .css() function applies css changes directly to elements rather than to the classes.
Thanks in advance!
You can do this in about 30 characters. Change:
$(".iframe-class").removeClass("iframe-class-resize")
to:
$(".iframe-class").removeClass("iframe-class-resize").css({ width : '', height : '' })
This will reset the width/height you applied to the element. When you use .css() you add whatever you pass-in to the style attribute of the element. When you pass a blank value, jQuery removes that property from the style attribute of the element.
Here is an updated fiddle: http://jsfiddle.net/TBJ83/3/
EDIT
OK, here's something tweaked for performance (and just some other ways to do things):
$(function () {
//setup these vars only once since they are static
var $myIFRAME = $(".iframe-class"),//unless this collection of elements changes over time, you only need to select them once
ogWidth = 700,
ogHeight = 600,
ogRatio = ogWidth / ogHeight,
windowWidth = 0,//store windowWidth here, this is just a different way to store this data
resizeTimer = null;
function setIFrameSize() {
if (windowWidth < 480) {
var parentDivWidth = $myIFRAME.parent().width(),//be aware this will still only get the height of the first element in this set of elements, you'll have to loop over them if you want to support more than one iframe on a page
newHeight = (parentDivWidth / ogRatio);
$myIFRAME.addClass("iframe-class-resize").css({ height : newHeight, width : parentDivWidth });
} else {
$myIFRAME.removeClass("iframe-class-resize").css({ width : '', height : '' });
}
}
$(window).resize(function () {
//only run this once per resize event, if a user drags the window to a different size, this will wait until they finish, then run the resize function
//this way you don't blow up someone's browser with your resize function running hundreds of times a second
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function () {
//make sure to update windowWidth before calling resize function
windowWidth = $(window).width();
setIFrameSize();
}, 75);
}).trigger("click");//run this once initially, just a different way to initialize
});
This can be done using pure CSS as below:
iframe {
height: 300px;
width: 300px;
resize: both;
overflow: auto;
}
Set the height and width to the minimum size you want, it only seems to grow, not shrink.
This is how I would do it, code is much shorter: http://jsfiddle.net/TBJ83/2/
<div class="container">
<iframe id="myframe" src="http://www.cnn.com/"></iframe>
</div>
<script>
$(function () {
setIFrameSize();
$(window).resize(function () {
setIFrameSize();
});
});
function setIFrameSize() {
var parentDivWidth = $("#myframe").parent().width();
var parentDivHeight = $("#myframe").parent().height();
$("#myframe")[0].setAttribute("width", parentDivWidth);
$("#myframe")[0].setAttribute("height", parentDivHeight);
}
</script>
I did it that way for read-ability, but you could make it even shorter and faster...
function setIFrameSize() {
f = $("#myframe");
f[0].setAttribute("width", f.parent().width());
f[0].setAttribute("height", f.parent().height());
}
One selector, so you only look through the DOM once instead of multiple times.
For those using Prestashop, this is how I used the code.
In the cms.tpl file I added the below code:
{if $cms->id==2}
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js?ver=1.3.2'></script>
<script type="text/javascript" src='../themes/myheme/js/formj.js'></script>
<div style="width: 100%; height: 800px;">
<iframe style=" width: 100%; height: 100%; border: overflow: auto;" src="https://cnn.com"></iframe>
</div>
{/if}
Then created a new js file: formj.js and added the below code:
$(function () {
//setup these vars only once since they are static
var $myIFRAME = $(".iframe-class"),//unless this collection of elements changes over time, you only need to select them once
ogWidth = 970,
ogHeight = 800,
ogRatio = ogWidth / ogHeight,
windowWidth = 0,//store windowWidth here, this is just a different way to store this data
resizeTimer = null;
function setIFrameSize() {
if (windowWidth < 480) {
var parentDivWidth = $myIFRAME.parent().width(),//be aware this will still only get the height of the first element in this set of elements, you'll have to loop over them if you want to support more than one iframe on a page
newHeight = (parentDivWidth / ogRatio);
$myIFRAME.addClass("iframe-class-resize").css({ height : newHeight, width : parentDivWidth });
} else {
$myIFRAME.removeClass("iframe-class-resize").css({ width : '', height : '' });
}
}
$(window).resize(function () {
//only run this once per resize event, if a user drags the window to a different size, this will wait until they finish, then run the resize function
//this way you don't blow up someone's browser with your resize function running hundreds of times a second
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function () {
//make sure to update windowWidth before calling resize function
windowWidth = $(window).width();
setIFrameSize();
}, 75);
}).trigger("click");//run this once initially, just a different way to initialize
});
Is there a way to reliably tell a browser's viewport width that includes the scrollbar, but not the rest of browser window)?
None of the properties listed here tell me the width of the screen INCLUDING the scrollbar (if present)
I figured out how to accurately get the viewport width WITH the scrollbar using some code from: http://andylangton.co.uk/blog/development/get-viewport-size-width-and-height-javascript
Put this inside your $(document).ready(function()
$(document).ready(function(){
$(window).on("resize", function(){
function viewport() {
var e = window, a = 'inner';
if (!('innerWidth' in window )) {
a = 'client';
e = document.documentElement || document.body;
}
return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}
});
// Get the correct window sizes with these declarations
windowHeight = viewport().height;
windowWidth = viewport().width;
});
What it Does:
When your page is 'ready' or is resized, the function calculates the correct window height and width (including scrollbar).
I assume you want to know the viewport width with scrollbar included, because the screen it self does not have a scrollbar. In fact the Screen width and heigth will be the computer screen resolution itself, so I'm not sure what you mean with screen width with the scroll bar.
The viewport however, the area where only the page (and scroll bars) is presented to the user, meaning, no browser menus, no bookmarks or whatever, only the page rendered, is where such scroll bar may be present.
Assuming you want that, you can measure the client browser viewport size while taking into account the size of the scroll bars this way.
First don't forget to set you body tag to be 100% width and height just to make sure the measurement is accurate.
body {
width: 100%;
// if you wish to also measure the height don't forget to also set it to 100% just like this one.
}
Afterwards you can measure the width at will.
Sample
// First you forcibly request the scroll bars to be shown regardless if you they will be needed or not.
$('body').css('overflow', 'scroll');
// Viewport width with scroll bar.
var widthWithScrollBars = $(window).width();
// Now if you wish to know how many pixels the scroll bar actually has
// Set the overflow css property to forcibly hide the scroll bar.
$('body').css('overflow', 'hidden');
// Viewport width without scroll bar.
var widthNoScrollBars = $(window).width();
// Scroll bar size for this particular client browser
var scrollbarWidth = widthWithScrollBars - widthNoScrollBars;
// Set the overflow css property back to whatever value it had before running this code. (default is auto)
$('body').css('overflow', 'auto');
Hope it helps.
As long as body is 100%, document.body.scrollWidth will work.
Demo: http://jsfiddle.net/ThinkingStiff/5j3bY/
HTML:
<div id="widths"></div>
CSS:
body, html
{
margin: 0;
padding: 0;
width: 100%;
}
div
{
height: 1500px;
}
Script:
var widths = 'viewport width (body.scrollWidth): '
+ document.body.scrollWidth + '<br />'
+ 'window.innerWidth: ' + window.innerWidth + '<br />';
document.getElementById( 'widths' ).innerHTML = widths;
I put a tall div in the demo to force a scroll bar.
Currently the new vw and vh css3 properties will show full size including scrollbar.
body {
width:100vw;
height:100vh;
}
There is some discussion online if this is a bug or not.
there is nothing after scrollbar so "rest of the window" is what?
But yes one way to do it is make another wrapper div in body where everything goes and body has overflow:none; height:100%; width:100%; on it, wrapper div also also has 100% width and height. and overflow to scroll. SO NOW...the width of wrapper would be the width of viewport
See Example: http://jsfiddle.net/techsin/8fvne9fz/
html,body {
height: 100%;
overflow: hidden;
}
.wrapper {
width: 100%;
height: 100%;
overflow: auto;
}
With jQuery you can calculate the browser's scrollbar width by getting the width difference when overflow: hidden is set and overflow: scroll is set.
The difference in width will be the size of the scrollbar.
Here is a simple example that shows how you could do this.
You can get the window width with scrollbar , that way:
function scrollbar_width() {
if (jQuery('body').height() > jQuery(window).height()) {
/* Modified from: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php */
var calculation_content = jQuery('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
jQuery('body').append(calculation_content);
var width_one = jQuery('div', calculation_content).innerWidth();
calculation_content.css('overflow-y', 'scroll');
var width_two = jQuery('div', calculation_content).innerWidth();
jQuery(calculation_content).remove();
return (width_one - width_two);
}
return 0;
}
Check out vw: http://dev.w3.org/csswg/css-values/#viewport-relative-lengths
body {
width: 100vw;
}
http://caniuse.com/#search=vw
This is my solution for removing the 'scrollbar shadow', because scrollWidth didn't work for me:
canvas.width = element.offsetWidth;
canvas.height = element.offsetHeight;
canvas.width = element.offsetWidth;
canvas.height = element.offsetHeight;
It's easy, but it works. Make sure to add a comment explaining why you assign the same value twice :)