3谈Iframe自融入高宽比编码

2021-03-22 07:07 jianzhan
在搭建B/S系统软件页面的情况下,常常会遇到首页面index.html中嵌套循环别的网页页面的状况 ,尽管早已有的库早已出示了控制(比如jQuery easy UI),可是有时iframe的应用是不能防止的,这篇文章内容应当给你1个相对性来讲较为好用的回答,正象文章内容所说,互联网技术上的绝大多数物品全是废弃物或是不能坚信的!原文有KOUBEI UED 由校 梳理!
为何是3谈
为何是3谈呢?1是由于这真的是1个被说烂的话题,2是由于太师傅在n年前就写过这篇再谈iframe自融入高宽比。之因此再提该难题,是由于以前新项目中的确遇到了这个难题的各个方面,必须总结1下。期待对各位有协助,有不正确请纠正。
同域、子网页页面高宽比不容易动态性提升
这类状况最简易,立即根据脚本制作获得字网页页面具体高宽比,改动iframe元素高宽比便可。但有2点务必留意:
假如网页页面内有肯定精准定位或沒有清波动的元素,状况一些繁杂,不一样访问器解决結果不一样,乃至包含Webkit核心的访问器,实际请看这个Demo。因此你要末开展访问器检验,要末用Math.max测算1个最大值,要末你想其他方式。
iframe所包括网页页面将会十分大,必须很长的载入時间,为此立即测算高宽比的情况下,极可能网页页面还没免费下载完,高宽比测算就会有难题。因此最好是在iframe的onload恶性事件中测算高宽比。这里还要留意的是,IE下务必应用微软恶性事件实体模型obj.attachEvent来关联onload恶性事件。而其他访问器立即obj.onload = function(){}还可以。

拷贝编码
编码以下:

(function(){
var frame = document.getElementById("frame_content_parent"),
setIframeHeight = function(){
var frameContent = frame.contentWindow.document,
frameHeight = Math.max(frameContent.body.scrollHeight,frameContent.documentElement.scrollHeight);
frame.height = frameHeight;
};
if(frame.addEventListener){
frame.addEventListener("load",setIframeHeight,false);
}else{
frame.attachEvent("onload",setIframeHeight);
}
})();

同域、子网页页面高宽比会动态性提升
基本原理与第1种状况1样,多1个计时器,1直检验字网页页面高宽比,当子网页页面高宽比和iframe的高宽比不1致时,再次设定iframe的高宽比。这边还可以加1个try在js错误时,加1个充足的高宽比。

拷贝编码
编码以下:

(function(){
var _reSetIframe = function(){
var frame = document.getElementById("frame_content_parent")
try {
var frameContent = frame.contentWindow.document,
bodyHeight = Math.max(frameContent.body.scrollHeight,frameContent.documentElement.scrollHeight);
if (bodyHeight != frame.height){
frame.height = bodyHeight;
}
}
catch(ex) {
frame.height = 1800;
}
}
if(frame.addEventListener){
frame.addEventListener("load",function(){setInterval(_reSetIframe,200);},false);
}else{
frame.attachEvent("onload",function(){setInterval(_reSetIframe,200);});
}
})();

同域、子网页页面高宽比会动态性提升、脚本制作将会彻底无效
第2个事例中,考虑到到了脚本制作错误的状况,可是万1脚本制作压根不实行了呢,那iframe中的內容就会由于iframe的高宽比不足而显示信息不上。为此大家一般事前设定1个充足的高宽比,以便前端开发操纵便捷,我感觉写在CSS文档中较为适合,必须改动时只改CSS就可以了。这里我设定了selector{ height:1800px; }。必须留意的是,写在款式表中的款式,不可以立即用node.style[property]来取,针对微软实体模型,要用node.currentStyle[property](题外话:不幸的IE实体模型不适用CSS伪类),针对W3C实体模型,要用window.getComputedStyle(node,null)[property]来取。我这里图便捷立即用了YUI。
这里又有1个难题,设定iframe的高宽比超过其包括网页页面的高宽比时,各个访问器的解决不1样。比如在Firefox下,务必测算body元素的高宽比,而html元素的高宽比等于iframe的高宽比,但是当正巧这个网页页面又有肯定精准定位、未清波动元素时,又不可以根据body元向来取,明显第1种方式缺陷更小1些。实际请看这个Demo。
从上面这个Demo能够看到,除IE访问器外,其他访问器测算出来的全是iframe的高宽比,即CSS里设定的#frame_content_parent{ height:1800px; }。而IE测算出来的是iframe所引入网页页面的具体高宽比。

拷贝编码
编码以下:

#frame_content_parent{ height:1800px; }
(function(){
var $ = YAHOO.util.Dom,
frame = $.get("frame_content_parent");
function reSetIframe(){
var frameContent = frame.contentWindow.document,
bodyHeight = Math.max(frameContent.documentElement.scrollHeight,frameContent.body.scrollHeight);
if (bodyHeight != $.getStyle(frame, "height")){
$.setStyle(frame, "height", bodyHeight + "px");
}
}
if(frame){
$.setStyle(frame,"height","auto");
setInterval(reSetIframe,300);
}
})();

跨域
这里出示1个Iframe代理商的方式,简易地说1下基本原理。假定有3个网页页面,各自是首页面A.html,字网页页面B.html,代理商网页页面C.html。在其中A与B是跨域的,而A和C是同域的。它们的关联:A包括B,B包括C。很明显A和B,和B和C,由于跨域不可以互相通讯,而A和C同域,能够互相通讯。为此大家就想起让C网页页面告知A网页页面,B网页页面究竟有是多少高。由于B和C也是跨域的不可以互相通讯,因此想在C网页页面中,立即window.parent.document.body.scrollHeight这样是行堵塞的,因此大家只能让B网页页面自身测算本身的高宽比,随后根据某种方式告知C网页页面,再由C网页页面告知A网页页面。这里的1个方式便是在B网页页面转化成1个Iframe连接点,随后设定它的src特性,在这个详细地址上额外1个主要参数,即B网页页面测算出来的高宽比,随后C网页页面便可以根据window.location获得这个详细地址栏中的详细地址,提取下高宽比值,根据window.top寻找A网页页面,设定A网页页面的Iframe的高宽比。基础的基本原理便是这样,看编码吧:
DEMO

拷贝编码
编码以下:

//B网页页面脚本制作
//每日任务:测算实际上际高宽比,随后转化成1个iframe连接点,将高宽比做为代理商网页页面C的详细地址的1一部分取值给Src特性
(function(){
var agent_iframe = document.createElement("iframe"),
b_height = Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
agent_iframe.src = "http://demo.zhouqicf.com/js/2010/iframe_height/agent_iframe_once.html#" + b_height;
document.body.appendChild(agent_iframe);
agent_iframe.style.display = "none";
})();


拷贝编码
编码以下:

//C网页页面脚本制作
//每日任务:获得恳求详细地址中的高宽比值,将其取值给A网页页面的Iframe的高宽比
window.top.document.getElementById("frame_content_parent").height = parseInt(window.location.hash.substring(1),10);

跨域、字网页页面高宽比动态性转变

这里融合了第2、第4两种方式,我的念头是在B网页页面根据1个计时器,不断测算B网页页面的高宽比,1但转变,立刻改动iframe标识的src特性,而C网页页面也是有计时器持续监视src的转变,更改Aiframe标识的高宽比。必须留意的是仅仅改动src特性后边的锚点值(如“#1234”),网页页面其实不会更新,不容易再次恳求,这也是在C网页页面提升计时器的缘故。


拷贝编码
编码以下:

//B网页页面脚本制作
(function(){
var getHeight = function(){
return Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
};
var preHeight = getHeight(),
agent_iframe;
var createIframe = function(height){
agent_iframe = document.createElement("iframe");
agent_iframe.style.height = "0";
agent_iframe.style.width = "0";
agent_iframe.style.border = "none";
agent_iframe.src = "http://demo.zhouqicf.com/js/2010/iframe_height/agent_iframe.html#" + height;
document.body.appendChild(agent_iframe);
}
createIframe(preHeight);
var checkHeight = function(){
var currentHeight = getHeight();
if(currentHeight != preHeight){
agent_iframe.src = "http://demo.zhouqicf.com/js/2010/iframe_height/agent_iframe.html#" + currentHeight;
preHeight = currentHeight;
}
setTimeout(checkHeight,500);
}
setTimeout(checkHeight,500);
})();


拷贝编码
编码以下:

//C网页页面脚本制作
(function(){
var preHeight = parseInt(window.location.hash.substring(1),10),
ifrmae = window.top.document.getElementById("frame_content_parent");
ifrmae.height = preHeight;
setInterval(function(){
var newHeight = parseInt(window.location.hash.substring(1),10);
if (newHeight !== preHeight){
ifrmae.height = newHeight;
preHeight = newHeight;
}
},500);
})();

这里也有另外一种计划方案,便是让iframe每次都再次恳求,这样C网页页面就不必须计时器了,可是假如2次测算高宽比反复的话,就会致使src特性的值同样,这样访问器就极可能不再次恳求该网页页面了,那末C网页页面中的脚本制作也就不运作了。要修补这个难题很简易,要是在每次测算出来的src特性上提升1个任意数的主要参数就可以了。例如http://demo.zhouqicf.com/js/2010/iframe_height/agent_iframe.html?temp=2937#1563


拷贝编码
编码以下:

//B网页页面重要脚本制作
agent_iframe.src = "http://demo.zhouqicf.com/js/2010/iframe_height/agent_iframe.html?a=" + Math.random() + "#" + currentHeight;
//C网页页面脚本制作
window.top.document.getElementById("frame_content_parent").height = parseInt(window.location.hash.substring(1),10);