没啥说的,前段时间遇到这个问题,需要解决
思想就是搞一个代理页面作为中转站,负责通知各个页面间高度发生的变化
本文的方案,是网络上众多方案中修改量最少的:每个页面只需修改一行代码即可
下面是我们要用到的一个公共的kissy-util-adaptive-frame.js
/** * 跨域iframe自适应高度解决方案 * Author: [email protected] <http://www.lzlu.com> * Copyright (c) 2011, Taobao Inc. All rights reserved. */ (function(){ var adaptFrame = new function(){ var doc = document, body = doc.body, self = this, //获取url中的参数 getRequest = function(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)","i"), r = window.location.search.substr(1).match(reg); return (r!=null)? unescape(r[2]) : null; }, //获取配置,script的优先级大于url中的参数 getConfig = function(){ //scripts对象一定要在这里赋值,不然取不到正确的script对象 var scripts = doc.getElementsByTagName('script'), script = scripts[scripts.length - 1]; return function(param){ var p = script.getAttribute(param); return p? p : getRequest(param); }; }(), //代理高度 proxyheight = 0, //top页frame的id frameid = getConfig("data-frameid"), //监听实时更新高度间隔 timer = getConfig("data-timer"), //获取代理的url getProxyuUrl = getConfig("data-proxy"), //创建代理的iframe proxyframe = function(){ var el = doc.createElement("iframe"); el.style.display = "none"; el.name="proxy"; return el; }(); //重置高度 this.resize = function(){ proxyheight = body.offsetHeight; proxyframe.src = getProxyuUrl + "?data-frameid=" + frameid+ "&data-frameheight=" + (proxyheight+40); } this.init = function(){ var init = function(){ body.appendChild(proxyframe); self.resize(); //是否update if(!isNaN(timer)){ timer = timer<500?500:timer; window.setInterval(function(){ if(body.offsetHeight != proxyheight){ self.resize(); } },timer); }; }; //如果引入KISSY(http://kissyui.com/), 建议改成:KISSY.ready(function(){init();}); if(doc.addEventListener){ window.addEventListener("load",init,false); }else{ window.attachEvent("onload",init); } } } adaptFrame.init(); })();
<%@ page language="java" pageEncoding="UTF-8"%> <!doctype html> <script type="text/javascript"> (function(){ var getRequest = function(name){ var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)","i"), r = window.location.search.substr(1).match(reg); return (r!=null)? unescape(r[2]) : null; }, height = getRequest("data-frameheight"); try { var el = window.top.document.getElementById(getRequest("data-frameid")); if (!el) return; el.style.height = height + 'px'; } catch (e) { //console.log(e); } })(); </script>
接下来进入主题。下面是位于123.125.xx.240机器上的main.jsp
<%@ page language="java" pageEncoding="UTF-8"%> <!doctype html> <h1>This is the main.jsp</h1> <iframe id="myMainFrame" src="http://123.125.xx.232:8092/ecpaycus/test/nested.jsp" scrolling="no" width="400" style="border:6px solid black;"></iframe>
最后是位于123.125.xx.232机器上的nested.jsp
<%@ page language="java" pageEncoding="UTF-8"%> <%-- 页面文档类型统一使用HTML5 DOCTYPE 本页面的大部分内容修改自http://www.lzlu.com/blog/?p=692,在此感谢作者常胤 关于本页面的编码规范,可参考http://docs.kissyui.com/docs/html/tutorials/styleguide/html-coding-style.html --%> <!doctype html> <h2>This is the nested.jsp</h2> <div id="box" style="width:300px; height:100px; background:red; padding:10px;">跨域iframe自适应高度的演示</div> <button id="btn">增高</button> <script type="text/javascript"> var btn = document.getElementById("btn"), box = document.getElementById("box"); btn.onclick = function(){ box.style.height = box.offsetHeight + 50 + "px"; } </script> <%-- Tips: 1)这里data-proxy的值(proxy.jsp)要与main.jsp位于同一个域下 Tips: 2)这里data-frameid的值要与main.jsp中<iframe id="myMainFrame">的id值一致 Tips: 3)这里data-timer实际上是指定JavaScript中定时器(它可用来实现实时自适应高度)参数的 --%> <script type="text/javascript" src="kissy-util-adaptive-frame.js" data-frameid="myMainFrame" data-timer="1000" data-proxy="http://123.125.xx.240:8804/ecpaycus/test/proxy.jsp"></script>
不过,我觉得上面这个例子不是很完善,下面再补充一个
用到的公共js和代理页面还是上面的kissy-util-adaptive-frame.js和proxy.jsp,不变
首先是位于123.125.xx.240机器上的main.jsp
<%@ page language="java" pageEncoding="UTF-8"%> <!doctype html> <h1>This is the main.jsp</h1> <iframe id="myMainFrame" src="http://123.125.xx.232:8092/ecpaycus/test/nested.jsp" scrolling="no" width="400" style="border:6px solid black;"></iframe>
<%@ page language="java" pageEncoding="UTF-8"%> <!doctype html> <%-- 2秒后自动转到至与main.jsp同域中的nested22.jsp --%> <meta http-equiv="refresh" content="2; URL=http://123.125.xx.240:8804/ecpaycus/test/nested22.jsp"> <h2>2秒后自动转到至nested22.jsp</h2> <div style="width:300px; height:100px; background:blue;">This is the nested.jsp</div> <script type="text/javascript" src="kissy-util-adaptive-frame.js" data-frameid="myMainFrame" data-timer="1000" data-proxy="http://123.125.xx.240:8804/ecpaycus/test/proxy.jsp"></script>
<%@ page language="java" pageEncoding="UTF-8"%> <!doctype html> <meta http-equiv="refresh" content="2; URL=nested33.jsp"> <h2>2秒后自动转到至nested33.jsp</h2> <div style="width:300px; height:200px; background:red;">This is the nested22.jsp</div> <script type="text/javascript" src="kissy-util-adaptive-frame.js" data-frameid="myMainFrame" data-timer="1000" data-proxy="proxy.jsp"></script>
<%@ page language="java" pageEncoding="UTF-8"%> <!doctype html> <h2>This is the nested33.jsp</h2> <div id="box" style="width:300px; height:300px; background:green;">This is the nested33.jsp</div> <script type="text/javascript" src="kissy-util-adaptive-frame.js" data-frameid="myMainFrame" data-timer="1000" data-proxy="proxy.jsp"></script>
备注:本文的解决方案,也适用于同域下<iframe>高度自适应的情况
补充:本文的机器地址都是HTTP的,如果某个页面是位于HTTPS下的,那也算是跨域
补充:此时自适应未必会生效,解决办法是让页面与其引用的公共JS和代理页面处于同协议下