zooming iframe to fit content (javascript)
I am trying to fit the contents of an iframe (same domain) into a pre-existing fixed-height iframe on my site.
The content is dynamically loaded into the pre-existing iframe, and then code in the iframe's body is executed which is supposed to scale it down or up so that the entire height/width is visible (that is, narrow/small documents scale up; long/wide documents scale down). Scaling is done using CSS Zoom until I think of a better way.
function squeezeFrame() {
var b=document.getElementsByTagName('body')[0],
h=document.getElementsByTagName('html')[0],
zW=(b.clientWidth-5)/b.scrollWidth,
z=zW,
s="",
mult=0.25, // max +- scaling cap
maxH = (typeof document.height !== 'undefined') ? document.height : Math.max( b.scrollHeight, b.offsetHeight, h.clientHeight, h.scrollHeight, h.offsetHeight ), // iframe content height
zH = (b.clientHeight)/maxH;
if (zH<zW && zH < 1) { z=zH } else { z=zW }; // single direction
if (z>1+mult) { z=1+mult; } else if (z<1-mult) { z=1-mult; }
s="zoom:"+z+";-moz-transform-origin: 0 0;-moz-transform: scale("+z+");";
if (typeof b.setAttribute === "function") b.setAttribute('style', s);
else if (typeof b.style.setAttribute === "object") b.style.setAttribute('cssText', s);
}
if ( typeof window.addEventListener != "undefined" ) window.addEventListener( "load", squeezeFrame, false );
else if ( typeof window.attachEvent != "undefined" ) window.attachEvent( "onload", squeezeFrame );
else {
if ( window.onload != null ) {
var chain = window.onload;
window.onload = function ( e ) {
chain( e );
squeezeFrame();
};
}
else window.onload = squeezeFrame;
}
However, the "scrollHeight" and "offsetHeight" and "clientHeight" are all the same value (to within a few pixels - the scrollbar width/height). Scroll Height does not represent the height that the document can scroll, it represents the height of the IFRAME on the parent document.
For example, if the height of the iframe content is 850px and the iframe itself is 550px, the iframe contents scrollHeight incorrectly returns "550".
How can I calculate the actual scroll height of the document?
Here's what I ended up doing. .pf
is a class that is just an identifier on the page (for multiple elements); .w0
and .h0
are classes on the div wrapping the content I want to scale down, and have style values assigning them particular pixel sizes.
<script>
(function (win, doc, undefined) {
function debounce(b,f,c){var a;return function(){var d=this,e=arguments,g=c&&!a;clearTimeout(a);a=setTimeout(function(){a=null;c||b.apply(d,e)},f);g&&b.apply(d,e)}};
var pagew = parseInt(win.getComputedStyle(doc.getElementsByClassName("w0")[0], null).getPropertyValue("width"),10),
pageh = parseInt(win.getComputedStyle(doc.getElementsByClassName("h0")[0], null).getPropertyValue("height"),10),
scaled = false;
[].forEach.call(doc.querySelectorAll(".pf"), function(elm) {
elm.style.transformStyle = "flat";
elm.style.transformOrigin = "top left";
});
var scaleDown = debounce(function() {
var docw = Math.max(doc.documentElement.clientWidth, win.innerWidth || 0);
if (docw < pagew) {
var scale = (docw / pagew);
[].forEach.call(doc.querySelectorAll(".pf"), function(el, i) {
var hdiff = ((pageh - el.getBoundingClientRect().height) * i) * -1;
el.style.transform = ["scale(",scale,",",scale,") translateY(",hdiff,"px)"].join("");
});
scaled = true;
} else if (scaled) {
[].forEach.call(doc.querySelectorAll(".pf"), function(el) {
el.style.transform = "scale(1,1) translateY(0px)";
});
scaled = false;
}
}, 250);
win.addEventListener('resize', scaleDown);
scaleDown();
})(window, document);
</script>
when the page resizes, if the pixel width of the page is more than the width of the window, it uses transform scale to scale the page down so that it fits. If subsequent .pf
classes are adjacent, it tries to use translateY to pull them towards each other (since scale doesn't change the flow height, I had to hack a negative offset to make them appear next to each other.
上一篇: 动态缩放iFrame内容以适应div宽度