I am using PrimeFaces 3 for this.
I have an iframe element inside a p:panel which is enhanced with a p:resizable component. What I want is to automatically resize the iframe on load and on resize event so that it fits the available width and height of the panel.
Note that in this example, there is a p element with some text in it before the iframe. So the relative origin of the iframe isn't a constant.
Here is the template code:
<h1>Page To Test Stuff</h1>
<script type="text/javascript">
function doIFrame(event, ui) {
var frame = document.getElementById("tFrame");
// now what?
}
</script>
<p:panel id="showit">
<p>
What I need is for the following iFrame (id="tFrame") to
automatically resize to the max available space inside
the surrounding panel. This needs to happen when the
window is initially drawn, and when the user clicks and
drags the resize icon.
</p>
<iframe id="tFrame"
src="http://www.apple.com"
/>
</p:panel>
<p:resizable for="showit" onStop="doIFrame(event, ui)"/>
My Javascript proficiency sucks but I am willing to learn. So I don't need more than a clue to get started.
You can get the element's client width and height by element.clientWidth and clientHeight. You can set the element's width and height by assigning element.width and element.height.
So, this should basically do it (roughly; I'm taking panel's default ~20px padding into account and I also assume that you removed that introductory <p>, else you have to take its client height into account as well):
var panel = document.getElementById("showit");
var frame = document.getElementById("tFrame");
frame.width = panel.clientWidth - 40;
frame.height = panel.clientHeight - 40;
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>
...
I have the following html :
<div id="this-is-slide">
<div id="left" style="float:left;width:70%;">
<!-- slide here -->
</div>
<div id="right" style="float:left;width:30%">
<div id="rightYT">You Tube video here...</div>
<div id="RightText">some text here</div>
</div>
</div>
Here, I have a slide which takes 70% of the width, while the other one (which includes You Tube video) takes 30% of the width. Under the YouTube video content I am having some text.
I want to set height to this div which has text in such a way that the total height of right side content (you tube & text) will be equal to the height of left side content(slider).
To do this I wrote JavaScript under "window.onload" and $(document).ready() but it is not calculating the height of the DIVs properly. I assume that JavaScript is running before EVERYTHING is loaded thereby giving wrong figures for the height at the initial load of the page.
However window resize is working, but at the initial time, its not doing the calculation properly.
This is my JS:
<script>
window.onload = function () { resizeRightText(); }
$(window).resize(function() {
resizeRightText();
});
function resizeRightText() {
var containerHeight = $('#left').height();
var youtubeHeight = $('#rightYT iframe').height();
var textHeight = containerHeight - youtubeHeight;
$('#RightText').css('height',textHeight);
}
</script>
Please let me know how to make it work in such a way that when the page loads FIRST TIME, I WANT TO SET THE HEIGHT TO THE TEXT DIV.
Thanks a bunch,
I'm trying to work out the algorithm for a fixed div that grows in height (while scrolling) until it's equal to the height of the viewport or div with fixed position relative to another div and the bottom of the viewport
I am using Twitter Bootstrap affix to lock my secondary navigation bar (yellow) and my sidebar (black) to the top of the screen when the user scrolls that far.
This works fine. The sidebar is the piece that's giving me trouble. When it is in its in its starting position (as shown in the diagram belorw), I want the top of the bar to sit 30px
down from the secondary navigation bar (yellow) and 30px up from the bottom of the page.
As the user scrolls, the bar should grow in height so that it remains 30px beneath the secondary navigation bar and 30px above the bottom of the screen (As shown in the diagram below)
After the bar is fixed position, I am able to do what I need to do.
.sidebar {
position:fixed;
top:100px;
bottom:30px;
left:30px;
}
What I can't figure out is how to position the TOP of the sidebar relative to my
secondary navigation bar and the BOTTOM of my sidebar relative to the bottom
of the screen. I've tried calculating the height of the sidebar at the beginning and the end of the
scroll but this causes issues.
I've also tried calculating the final height of the sidebar and letting the bottom of
the sidebar just run off the edge of the screen (when it's in its initial position), but
if there's not enough content on the right side to warrant scrolling, I have no way
of getting to the bottom items in the scroll bar. Plus my screen starts bouncing
in a really unattractive way.
below is the current code in use:
ShelvesSideBar.prototype._resize_sidebar = function(_this) {
var PADDING = 50;
var window_height = $(window).height(),
nav_bar_height = $('.nav_bar').height() + $('.secondary_tabs').height(),
sidebar_height = window_height - nav_bar_height - PADDING,
sidebar_scrollable_height = sidebar_height - $('.bar_top').height();
_this.$container.height(sidebar_height);
_this.$container.find('.bar_bottom').height(sidebar_scrollable_height);
/* reset the nanoscroller */
_this.$container.nanoScroller();
};
this code is called on page load and again on window resize. Any help would be greatly appreciated!
I've been trying to do something similar (minus the fixed elements and navbars). What I found was in order to do any sort of relative height scaling every element above the element I wished to scale all the way up to the opening html tags had to have a relative height set, even if it was just height:100%;. (here's my original question Variable height, scrollable div, contents floating)
My goal was to have the body height fixed to window size like a native full screen application would be with my content subareas scrolling, so this is a bit off topic for what you're wanting to accomplish. But I tried using JS/JQ to start off with as you're trying to do currently and found that I simply couldn't get the window height because the default behaviour for height management is to expand the page height until everything on the page fits. And all the getHeight methods I tried we're getting the page height not window/viewport height as promised. So you may wish to try fixing your body's height to the window and going from there using overflow:scroll; to scroll the page.
A quick note on overflow:scroll; if you have users who use WP8 IE (and probably other versions of IE) it may be advantageous to implement FTscroller to handle all your scroll elements as the overflow property defaults to hidden and is a fixed browser property. The only problem with FTscroller is because it uses CSS offsets to move the content container it may wreak havoc on elements that are designed to switched to fix when they reach x height from top of page because technically the top of page (or rather the top of the container they're in) isn't at the top of the page anymore it's beyond it. Just something to be aware of if you do need to cater for this browser.
And apologies for the complexity of my sentence structure. :/
so I was able to figure this out, for anyone still looking. What I ended up doing was binding to the window scroll event and - whenever the scroll occurred - I check if the class "affix" has been added to the sidebar. If it has, then I perform one set of calculations to determine sidebar height. Otherwise, I perform the other set of calculations. Code below:
/* called on window scroll */
var PADDING = 70;
var window_height = $(window).height(),
nav_bar_height = $('.nav_bar').height() + $('.secondary_tabs').height(),
header_height = $('.prof_block').height() - nav_bar_height,
sidebar_height = _this.$container.hasClass("affix") ? window_height - nav_bar_height - PADDING : window_height - (header_height + nav_bar_height) - PADDING,
sidebar_scrollable_height = sidebar_height - $('.bar_top').height();
_this.$container.height(sidebar_height);
_this.$container.find('.bar_bottom').height(sidebar_scrollable_height);
Basically I have a list of divs like this:
<div id="1">First div</div>
<div id="2">Second div</div>
and I want the most visible div to affect what is displayed in a different constant div, like this:
<div id="link">First div's link</div> (If the first div took up most of the page)
And then
<div id="link">Second div's link</div> (If the second div is scrolled to)
How would I get the Javascript to figure out which div is being viewed (calculated by which is taking up the greatest % of pixel space on the screen) and then trigger an event for the 'link' div based on that?
EDITING MY PREVIOUS ANSWER.
You have to find out how far each div is from the top of the document (it's a fixed number, regardless of how far the window is scrolled down):
divTop = $('#1').offset().top
Then, find out how far the window is scrolled:
scrollTop = $(document).scrollTop()
You also need the window's height (which is the height of visible portion of the document):
windowHeight = $(window).height()
And, you need the height of each div:
divHeight = $('#1').height().
Then you calculate where each div starts relative to the top of the window, which could be a negative number -- if the window is scrolled down past the top of the div -- in which case you make it zero, using Math.max:
divTopInWindow = Math.max(0, divTop - scrollTop)
Similarly, you calculate the div's bottom, relative to the top of the window. If the div extends past the bottom of the window, you make it the window's height:
divBottomInWindow = Math.min(windowHeight, divTop + divHeight - scrollTop)
Finally, you figure out the percent visible of each div like so (actually it's the fraction, not the percent, but whatever):
percentVisible = (divBottomInWindow - divTopInWindow) / windowHeight
I haven't tried it, so there may be a mistake in there, but it's definitely the right approach.
-------------------------- OLD ANSWER BELOW JUST FOR REFERENCE ------------------
I don't think you're using the expression "trigger an event" properly. Sounds like you just want to set the content of a div based on some condition (i.e. whether div 1 is taller than div 2).
Assuming you have jQuery or Zepto loaded on the page:
if( $('#1').height() > $('#2').height() ) {
$('#link').html('First div link');
}
else {
$('#link').html('Second div link');
}
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.