Resize iframe to content with Jquery - javascript

I'm trying to resize an iframe dynamicly to fit its content. To do so I have a piece of code:
$("#IframeId").height($("#IframeId").contents().find("html").height());​
It doesnt work. Is it because of cross-domain issue? How do I get it to fit? Please take a look at Fiddle: JsFiddle
ps I have set the html and body of the link height:100%;

You just need to apply your code on the iframe load event, so the height is already known at that time, code follows:
$("#IframeId").load(function() {
$(this).height( $(this).contents().find("body").height() );
});
See working demo . This demo works on jsfiddle as I've set the iframe url to a url in the same domain as the jsfiddle result iframe, that is, the fiddle.jshell.net domain.
UPDATE:
#Youss:
It seems your page for a strange reason don't get the body height right, so try using the height of the main elements instead, like this:
$(document).ready(function() {
$("#IframeId").load(function() {
var h = $(this).contents().find("ul.jq-text").height();
h += $(this).contents().find("#form1").height();
$(this).height( h );
});
});

Not sure why #Nelson's solution wasn't working in Firefox 26 (Ubuntu), but the following Javascript-jQuery solution seems to work in Chromium and Firefox.
/**
* Called to resize a given iframe.
*
* #param frame The iframe to resize.
*/
function resize( frame ) {
var b = frame.contentWindow.document.body || frame.contentDocument.body,
cHeight = $(b).height();
if( frame.oHeight !== cHeight ) {
$(frame).height( 0 );
frame.style.height = 0;
$(frame).height( cHeight );
frame.style.height = cHeight + "px";
frame.oHeight = cHeight;
}
// Call again to check whether the content height has changed.
setTimeout( function() { resize( frame ); }, 250 );
}
/**
* Resizes all the iframe objects on the current page. This is called when
* the page is loaded. For some reason using jQuery to trigger on loading
* the iframe does not work in Firefox 26.
*/
window.onload = function() {
var frame,
frames = document.getElementsByTagName( 'iframe' ),
i = frames.length - 1;
while( i >= 0 ) {
frame = frames[i];
frame.onload = resize( frame );
i -= 1;
}
};
This continually resizes all iframes on a given page.
Tested with jQuery 1.10.2.
Using $('iframe').on( 'load', ... would only work intermittently. Note that the size must initially be set to 0 pixels in height if it is to shrink below the default iframe height in some browsers.

What you can do is the following:
Within the iFrame use document.parent.setHeight(myheight) to set the height within the iFrame to the parent. Which is allowed since it is a child control. Call a function from the parent.
Within the parent you make a function setHeight(iframeheight) which resizes the iFrame.
Also see:
How do I implement Cross Domain URL Access from an Iframe using Javascript?

Just do it on the HTML tag, works perfect
$("#iframe").load(function() {
$(this).height( $(this).contents().find("html").height() );
});

As the answer to the question use an already outdated jquery (load has been deprecated and replaced with .on('load',function(){}), below is the latest code for the answer in the question.
Note that I use the scrollHeight and scrollWidth, which I think will load much nicer than using Height and Width like the answer provided. It will totally fit, without scroll anymore.
$("#dreport_frame").on('load',function(){
var h = $('#dreport_frame').contents().find("body").prop('scrollHeight');
var w = $('#dreport_frame').contents().find("body").prop('scrollWidth');
$('#dreport_frame').height(h);
$('#dreport_frame').width(w);
})

Adjust height of an iframe, on load and resize, based on its body height.
var iFrameID = document.getElementById('iframe2');
var iframeWin = iFrameID.contentWindow;
var eventList = ["load", "resize"];
for(event of eventList) {
iframeWin.addEventListener(event, function(){
if(iFrameID) {
var h = iframeWin.document.body.offsetHeight + "px";
if(iFrameID.height == h) {
return false;
}
iFrameID.height = "";
iFrameID.height = iframeWin.document.body.offsetHeight + "px";
}
})
}

At end, I come with this cross-domain solution that work also for resize...
(resize not triggering : Auto resize iframe height when the height of the iframe contents change (same domain) )
Iframe :
(function() {
"use strict";
var oldIframeHeight = 0,
currentHeight = 0;
function doSize() {
currentHeight = document.body.offsetHeight || document.body.scrollHeight;
if (currentHeight !== oldIframeHeight) {
console.log('currentHeight', currentHeight);
window.parent.postMessage({height:currentHeight}, "*");
oldIframeHeight = currentHeight;
}
}
if (window.parent) {
//window.addEventListener('load', doSize);
//window.addEventListener('resize', doSize);
window.setInterval(doSize, 100); // Dispatch resize ! without bug
}
})();
Parent page :
window.addEventListener('message', event => {
if (event.origin.startsWith('https://mysite.fr') && event.data && event.data.height) {
console.log('event.data.height', event.data.height);
jQuery('#frameId').height(event.data.height + 12);
}
});

Related

Bootstrap responsive iframe with auto height calculation

I need to embed link in iFrame contents of the iframe are responsive and i want iframe to auto adjust to the height of iFrame so that whole iframe page is visible.
http://quran.ksu.edu.sa/m.php
Fiddle http://jsfiddle.net/ww09rtbb/3/
I am not sure how to do it so that all content of iframe are visible.
Not sure if there is any build in css property to do it or i have to use jquery for it
UPDATED:
I have somehow managed to do it with jquery
http://jsfiddle.net/ww09rtbb/5/
I am calculating and multiplying width by 1.8
var ifrmw = $('.content-wrapper' ).width();
var iframeh= ifrmw * 1.8;
//alert(iframeh);
$('.iframecls').css('min-height',iframeh);
This can further be improved to to get exact height of iframe
I ran into a similar issue, and I had to write a function that checks for the height of the iframe every 200 milliseconds using setInterval():
function adjustIframeHeight(iframe, minHeight, fix){
var height = 0, $frame = $(iframe);
if(typeof fix=='undefined') fix = 0;
setInterval(function(){
if( typeof $frame.contents()!=null && typeof $frame.contents() !='undefined' && $frame.contents() !=null && $frame.attr('src')!='') {
curHeight = $frame.contents().find('body').height();
$frame.css('height', height + fix); // you might need to add some extra values like +20px.
} else {
$frame.css('height', minHeight); // minimum height for the iframe.
}
},200);
}
Then call it like this:
$(function(){
adjustIframeHeight('#iframeID', 200, 0);
});

Make two elements have the same size

I want two elements in different locations and different "parents" in the DOM tree to have the same height and width, even if one changes.
Is there a solution that will support all browsers including IE 8?
EDIT: If there is a solution that will not work on IE 8 I would still like to hear about it, but it will not be accepted as the solution I'm looking for.
Clarification: I want to solution to handle any cause for the size change: Window size change, content size change, etc.
You can use setInterval to do what you want.
var changeIndex = -1; // record element width or height is change or not
function setToSame() {
if(changeIndex!=-1) {
console.log("test");
$('.same').height($('.same').eq(changeIndex).height());
$('.same').width($('.same').eq(changeIndex).width());
changeIndex = -1;
}
}
// set your own function to change size, but reserve changeIndex setting
$('input').change(function() {
$(this).parent().children('.same').css($(this).attr('id'), $(this).val() +'px');
// set the changeIndex to the current change div
changeIndex = $('.same').index($(this).parent().children('.same'));
console.log(changeIndex);
});
setInterval(setToSame, 4);
See jsfiddle here.
You can use jQuery to get a solution that works for IE8.
Suppose the two element that you want to have same height and width are,
<div id="fir">
</div>
<div id="sec">
</div>
Now specify height and width of just one element as,
#fir{
height: 50px;
width: 100px;
}
There is no predefined method in CSS to detect height or width change but you can achieve the results using jQuery as,
$(document).ready(function(){
$('#fir').bind('heightChange', function(){
var h = $("#fir").height();
$("#sec").height(h);
});
$('#fir').bind('widthChange', function(){
var w = $("#fir").width();
$("#sec").width(w);
});
$('#sec').bind('heightChange', function(){
var h = $("#sec").height();
$("#fir").height(h);
});
$('#sec').bind('widthChange', function(){
var w = $("#sec").width();
$("#fir").width(w);
});
});
This will detect the height and width change for both element and set the height and width of other element likewise.
To check if the above code works properly you can create a test script that changes width of element with id="fir" by creating a button,
<button id="btn">Change width</button>
Now include the below function,
$("#btn").click(function() {
$("#fir").css('width', '400px');
$("#fir").trigger('widthChange');
});
Here is the fiddle for it
<html>
<head>
<style>
div{}
#A{background: red}
#B{background: blue}
</style>
<script>
mBlockChange = false; //Required for IE9-
function equalSize(f, t){
mBlockChange = true;
f = (f || document.getElementById('A'));
t = (t || document.getElementById('B'));
//We take the larger dimension of both since it is better than clipping.
//Change on your demands.
t.style.height = '';
t.style.width = '';
f.style.height = '';
f.style.width = '';
t.style.height = Math.max(f.offsetHeight, t.offsetHeight).toString() + 'px';
t.style.width = Math.max(f.offsetWidth, t.offsetWidth).toString() + 'px';
f.style.height = Math.max(f.offsetHeight, t.offsetHeight).toString() + 'px';
f.style.width = Math.max(f.offsetWidth, t.offsetWidth).toString() + 'px';
setTimeout(function(){mBlockChange = false}, 100);
}
//This one for IE9+, FFox, Chrome and Safari
//http://help.dottoro.com/ljrmcldi.php
function bindEvents(){
var tA = document.getElementById('A');
var tB = document.getElementById('B');
//The addEventListener() method is not supported in Internet Explorer 8 and earlier versions with resize.
//Resizing the body
document.body.onresize = function(){
//We only do this once the resizing is actually finished.
if (this.Timer) clearTimeout(this.Timer);
this.Timer = setTimeout(function(){
//console.log('Resize', this);
equalSize()
}, 300)
};
//If supported, we listen on dom changes.
if ('MutationEvent' in window){
document.addEventListener('DOMSubtreeModified', function(){
if (document.Timer) clearInterval(document.Timer);
//console.log('DOMSubtreeModified', this);
if (!mBlockChange) equalSize()
}, false);
}
//We set an interval for browsers which do not support DOMSubtreeModified
//If you do not want to rely on ('MutationEvent' in window) put it out of else and cancel the timer (scenario B)
//Can not bind parameters to setInterval in IE8- :s
else{
document.Timer = setInterval(function(){
//console.log('Interval', 'Document');
equalSize()
}, 1000);
}
}
</script>
</head>
<body onload = 'bindEvents()'>
<div id = 'A'><p contenteditable = 'true'>A</p></div>
<div id = 'B'><p contenteditable = 'true'>B</p></div>
</body>
</html>
https://jsfiddle.net/5cn7maqe/
Yet your elements height and width should not magically change, it always requires some interactions, like changing dom by ajax, oninput with contenteditable or resizing the window. You would be better off to just adjust it after those actions manually.
Edit: Made some minor changes.
https://jsfiddle.net/5cn7maqe/1/

jQuery function on window events (load and resize)

I'm not sure how to use the order of the window events load and resize on jQuery to make it work when resizing. The first function is used to get the total width except the scrollbar width, because the CSS is using the device width, but the JS is using the document width.
The second function adds a style when the total screen width is between 768px and 1024px, and it should work when I load the page at any screen, after resizing, etc. I'm doing a lot of tests and I think the problem is about the window events order.
For being more specific about the problems, it doesn't remove the style when I load the page at 900px and I expand it to > 1024px! Or by the contrary, it doesn't add the style when I load the page at 1300px and I shorten the width to 900px.
I think it's 'cause of the load and resize events order, but I'm not totally sure. Or maybe I'm not doing the correct declaration of the variable into the resize.
The code:
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' ] };
}
$(document).ready(function(){
var vpwidth=$(window).width();
$(window).on('resize', function(){
var changeWidth = (($('.main-content .wrap').width() * 96.3)/100) - 312;
if(vpwidth >= 768 && vpwidth <= 1024) {
$('.contentleft, .contentright').css('width', changeWidth + 'px');
} else {
$('.contentleft, .contentright').removeAttr('style');
}
}).resize();
});
I believe the issue is that you're not re-calculating the vpwidth on resize, So the value you got when the page was loaded will be used every time window is resized.
try
$(document).ready(function(){
$(window).on('resize', function(){
var vpwidth=$(window).width(); // get the new value after resize
var changeWidth = (($('.main-content .wrap').width() * 96.3)/100) - 312;
if(vpwidth >= 768 && vpwidth <= 1024) {
$('.contentleft, .contentright').css('width', changeWidth + 'px');
} else {
$('.contentleft, .contentright').removeAttr('style');
}
}).resize();
});
The issue is because you are not recalculating the width (vpwidth) on resize function.
It is initialized and set on page load itself and hence doesn't change when the window is resized causing the style to not be added or removed.
You need to re-assign the value to the variable from within the resize function.
$(window).on('resize', function(){
var vpwidth=$(window).width();
}
Demo Fiddle

How to change the height of div with the content of other div

I have two div in my website page one beside the other(one left and one right),I want to change the height of the left one with the content of the right one using javascript
I tried to have the dynamic height of the right div :
function getHeight() {
var doc = document.getElementById('div.right');
if (document.all) // ok I.E
{
H = doc.currentStyle.height;
}
else // ok FF
{
H = document.defaultView.getComputedStyle(doc, null).height;
}
}​
But I stopped here because I don't know how to pass the javascript variable to my page of style CSS,I mean I dont know how to apply this value in the other div(left div) in the same page automatically.
Any Idea?
Just use
document.getElementById('div.left').style.height = H;
Edit
AFAIK you cant modify an external stylesheet from javascript
Is the height of the div determined at the time the document is served, loaded or or any arbitrary time after the document has loaded?
The code I suggested above was to be used like this(I'm assuming your IE code is correct)
function getHeight() {
var doc = document.getElementById('div.right');
if (document.all) // ok I.E
{
H = doc.currentStyle.height;
}
else // ok FF
{
H = document.defaultView.getComputedStyle(doc, null).height;
}
document.getElementById('div.left').style.height = H;//✔
}
Just to help people I found a great code to change the height of two div autoamtically using a little of Jquery :
<script type='text/javascript'>
$(window).load(function(){
var lh = $('#div.right').height();
var rh = $('#div.left').height();
if (lh >= rh){
//alert('left : ' + lh);
$('#div.left').height(lh);
} else {
//alert('right : ' + rh);
$('#div.right').height(rh);
};
});
</script>
It's works for all navigators.

jquery or not / Cross Browser Compatible iframe resize (IE, Chrome, Safari, Firefox)

Here is my issue. I have been looking hard for a cross browser iframe resize code to use and i just cant find one. All i have seen has issues in one browser over another. Here is what i am doing. I am loading an iframe into the page in an jquery tools overlay. This iframe will load contents of a page (on the same domain so dont need to worry about cross domain). When a user clicks an action on that form the iframe will again need to resize (i have it working for when the iframe increases but not when the iframe decreases).
I have a js file that is included in the iframe which has this function
$(window).load(function(){
parent.adjust_iframe();
});
That function then calls the parent pages function like so:
function adjust_iframe() {
//i have tried both body and html and both dont work in IE
var h = $("#overlayFrame").contents().find("body").height();
if(h==0)
h="500";
else
h=h+3;
$("#overlayFrame").css({'height': h});
window.scrollTo(0,0);
}
The above code works fine in Chrome and firefox but not in IE.
Any help here? I really need a cross browser compatible light weight solution that doesnt involve some heavy jquery plugin that isnt supported.
Thanks!
Try
$(window).load(function(){
var bodyHeight = $('body').height();
parent.adjust_iframe( bodyHeight );
});
and
function adjust_iframe(newHeight) {
//i have tried both body and html and both dont work in IE
if(newHeight == 0) {
newHeight = 500;
} else {
newHeight += 3;
}
$("#overlayFrame").css({'height': newHeight});
window.scrollTo(0,0);
}
Because the problem is probably that the page cannot access the iframes contents..
I have 2 suggestions:
When you are setting the CSS height, explicitly tell it pixels.
$("#overlayFrame").css({'height': h + 'px'});
When your iframe code is calling parent.adjust_iframe, send the current width/height.
parent.adjust_iframe($('body').height());
BONUS suggestion: Do a little investigation and tell us what version of IE and why it doesn't work. Put some alerts in there and find out if the height is getting derived etc.
I've searched my archived files and found script which sets new size of iframe window. It was working on IE6, FF,...
/**
* Parent
*/
<iframe id="myframe" name="myframe" ...>
<script type="text/javascript">
var iframeids=["myframe"];
if (window.addEventListener) {
window.addEventListener("load", resizeCaller, false);
}else if (window.attachEvent) {
window.attachEvent("onload", resizeCaller);
} else {
window.onload=resizeCaller;
}
var iframehide="yes";
var getFFVersion=navigator.userAgent.substring(navigator.userAgent.indexOf("Firefox")).split("/")[1];
var FFextraHeight=parseFloat(getFFVersion)>=0.1? 20 : 0;
function resizeCaller() {
var dyniframe=new Array();
for (i=0; i<iframeids.length; i++){
if (document.getElementById)
resizeIframe(iframeids[i]);
if ((document.all || document.getElementById) && iframehide=="no"){
var tempobj=document.all? document.all[iframeids[i]] : document.getElementById(iframeids[i]);
tempobj.style.display="";
}
}
};
function resizeIframe(frameid){
var currentfr=document.getElementById(frameid);
if (currentfr && !window.opera){
currentfr.style.display="";
if (currentfr.contentDocument && currentfr.contentDocument.body.offsetHeight)
currentfr.height = currentfr.contentDocument.body.offsetHeight+FFextraHeight;
else if (currentfr.Document && currentfr.Document.body.scrollHeight)
currentfr.height = currentfr.Document.body.scrollHeight;
if (currentfr.addEventListener)
currentfr.addEventListener("load", readjustIframe, false);
else if (currentfr.attachEvent){
currentfr.detachEvent("onload", readjustIframe);
currentfr.attachEvent("onload", readjustIframe);
}
}
};
function readjustIframe(loadevt) {
var crossevt=(window.event)? event : loadevt;
var iframeroot=(crossevt.currentTarget)? crossevt.currentTarget : crossevt.srcElement;
if (iframeroot)resizeIframe(iframeroot.id);
};
function loadintoIframe(iframeid, url){
if (document.getElementById)document.getElementById(iframeid).src=url;
};
</script>
/**
* child iFrame html
*/
<body onResize="resizeIE()">

Categories

Resources