Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
605 views
in Technique[技术] by (71.8m points)

javascript - Auto resize iframe height when the height of the iframe contents change (same domain)

I am loading an iframe inside a page, which the length of the content of the iframe will be changed from time to time. I have implemented the following solution. However the height is fixed as the dyniframesize only get call when iframe.onload.

It is possible to have the iframe to be resized accordingly from time to time the height of the iframe changed?

<iframe src ="popup.html" frameborder="0" marginheight="0" marginwidth="0" frameborder="0" scrolling="auto" id="ifm" name="ifm" onload="javascript:dyniframesize('ifm');" width="100%"></iframe> 

function dyniframesize(down) { 
var pTar = null; 
if (document.getElementById){ 
pTar = document.getElementById(down); 
} 
else{ 
eval('pTar = ' + down + ';'); 
} 
if (pTar && !window.opera){ 
//begin resizing iframe 
pTar.style.display="block" 
if (pTar.contentDocument && pTar.contentDocument.body.offsetHeight){ 
//ns6 syntax 
pTar.height = pTar.contentDocument.body.offsetHeight +20; 
pTar.width = pTar.contentDocument.body.scrollWidth+20; 
} 
else if (pTar.Document && pTar.Document.body.scrollHeight){ 
//ie5+ syntax 
pTar.height = pTar.Document.body.scrollHeight; 
pTar.width = pTar.Document.body.scrollWidth; 
} 
} 
} 
</script> 
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To my knowledge, there isn't a very natural way of doing this, but there are some options.

setInterval()

You could use setInterval() to repeatadly check the iframe's content height and adjust it if needed. This is simple, but inefficient.

Event Listeners

Any change of content in the iframe's content (and therefore height) is usually triggered by some event. Even if you're adding content from outside of the iframe, that "add" is probably triggered by a button click, for example. Here's something that might work for you: Live demo here (click).

var myIframe = document.getElementById('myIframe');

window.addEventListener('click', resizeIframe);
window.addEventListener('scroll', resizeIframe);
window.addEventListener('resize', resizeIframe);

myIframe.contentWindow.addEventListener('click', resizeIframe);

function resizeIframe() {
  console.log('resize!');
}

Mutation Observer

This solution works in all up-to-date browsers - http://caniuse.com/mutationobserver

Live demo here (click).

It's really simple and should catch the relevant changes. If not, you could combine it with the event listener solution above to be sure things are updated!

var $myIframe = $('#myIframe');
var myIframe = $myIframe[0];

var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

myIframe.addEventListener('load', function() {
  setIframeHeight();

  var target = myIframe.contentDocument.body;

  var observer = new MutationObserver(function(mutations) {
    setIframeHeight();
  });

  var config = {
    attributes: true,
    childList: true,
    characterData: true,
    subtree: true
  };
  observer.observe(target, config);
});

myIframe.src = 'iframe.html';

function setIframeHeight() {
  $myIframe.height('auto');
  var newHeight = $('html', myIframe.contentDocument).height();
  $myIframe.height(newHeight);
}

Honorable mention to: overflow/underflow events.

Read about it here (there's A LOT to it).

and see my demo here (doesn't work in IE 11!).

This was a cool solution, but it's no longer working in IE. It might be possible to tweak it, but I'd rather use one of the above solutions, even if I had to fallback to a 1 second setInterval for older browsers, just because it's a lot simpler than this solution.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...