需求:
在一个页面中通过iframe标签签入一个页面,通过操作iframe标签内的页面来切换iframe的页面.
即通过iframe内子页面来调用父页面的方法实现功能,当 两个页面域名不同,要跨域操作.
解决方案:
跨域的调用,调用属性/函数的页面与被调用属性/函数的页面处于同一个域,这里使用一个中间页面.因为是子页面调用父页面,所以中间页面的域名同父页面.
代码:
父页面:
http://localhost:8080/TomcatTest/Page.html
<iframe src="http://10.110.80.186/jcms/publish/zglh/zxggpc/" οnlοad="changeFrameHeight()"
id="myframe" name="myframe" width="100%" frameborder="0" scrolling="no"></iframe>
子页面:
http://10.110.80.186/jcms/publish/zglh/zxggpc/
点击一个a标签,得到一个URL,传给中间页面,在传给父页面,调用父页面方法切换iframe标签的src属性
<a href="${contentList.CM_PUBLISHPATH}"> ${contentList.CM_TITLE}</a>
<script>
$("#pagelist a").click(function(){
var url = $(this).attr("href"); //得到父页面iframe要切换的URL
stayPage(url);
return false; //阻止当前a标签的跳转
})
//跨域 使用第三方页面,操作父页面方法
function stayPage(toUrl) {
var h;
var imgSrc;
$.ajax({
url: toUrl, //请求得到的URL,得到整个页面html代码,词ajax请求要得到当前页面的height
data: {},
contentType: "html",
async:false,
success: function (contend) {
$("#bodyHeight").html(contend) //得到此页面的height,传给父页面以实现 iframe 不同页面高度自适应
h = $("#bodyHeight").height()
imgSrc= getImgSrc(); //得到此页面的所有图片URL,上面的h变量不包括图片高度,因为图片大小为auto,在此页面通过window.οnlοad=function(){} 获取图片实际高度是要图片资源加载完成才行,但此时父页面iframe标签已经完成跳转,没用了,这里将图片URL传给父页面处理
})
// 中间页面:http://localhost:8080/TomcatTest/execA.html, 通过URL传给中间页面三个参数
if(typeof(exec_obj)=='undefined'){
exec_obj = document.createElement('iframe');
exec_obj.name = 'execframe';
exec_obj.src = 'http://localhost:8080/TomcatTest/execA.html?url='+toUrl+'&height='+h+'&imgSrc='+imgSrc;
exec_obj.style.display = 'none';
document.body.appendChild(exec_obj);
}else{
exec_obj.src='http://localhost:8080/TomcatTest/execA.html?' + Math.random()+"&url="+toUrl+'&height='+h+'&imgSrc='+imgSrc;
}
}
//得到页面所有图片的URL
function getImgSrc(){
var src="";
$("#bodyHeight img").each(function(index,domEle){
if(index ==0)
src += $(this).attr("src");
else
src += ","+$(this).attr("src");
});
return src;
}
</script>
中间页面:在父页面的项目里创建
http://localhost:8080/TomcatTest/execA.html
<body>
<h3>execA</h3>
<script type="text/javascript">
var url = location.search; //获取子页面通过URL传的参数
var src = url.substring(url.indexOf("url=")+4,url.indexOf("&height"))
var height = url.substring(url.indexOf("height=")+7,url.indexOf("&imgSrc"))
var imgSrc = url.substring(url.lastIndexOf("=")+1)
parent.parent.change(src,height,imgSrc); //调用父页面change方法
</script>
</body>
父页面:
传过来三个参数,src 用于替换iframe的src属性值,
height用于设置iframe的高度
imgSrc用于获取每个图片的真实高度
<script>
function changeFrameHeight(){
var ifm= document.getElementById("myframe");
ifm.height=document.documentElement.clientHeight;
}
window.οnresize=function(){
changeFrameHeight();
}
function change(src,height,imgSrc){
var h = Number(height)+110; //定义iframe的父标签高度
if(imgSrc != "") { //根据图片URL 获取图片高度
var imgArr = imgSrc.split(",");
imgArr.forEach(function(ele,index){
// 这里做下说明,$("<img/>")这里是创建一个临时的img标签,类似js创建一个new Image()对象!
var img = $("<img/>").attr("src", ele)
h += img[0].height //img[0].height 即为当前图片高度, 添加到 height 上去,这里不用load方法也可以获取,用下面的load方法也可以获取,但load方法中 如果图片地址无效,报notfound错误,则程序无法执行下去
height = h-110
// img.load(
// function() {
// /*
// * 如果要获取图片的真实的宽度和高度有三点必须注意 1、需要创建一个image对象:如这里的$("<img/>")
// * 2、指定图片的src路径 3、一定要在图片加载完成后执行如.load()函数里执行
// */
// h += this.height
// height = h-110
if(index == imgArr.length-1){
$(".homepage_main").css("height",h);
$("#myframe").css("height",height);
if(src.indexOf("http")== -1) / /传的src可能是相对地址
$("#myframe").attr("src","http://10.110.80.186/jcms/publish/zglh/zxggpc/"+src);
else
$("#myframe").attr("src",src);
document.getElementById("demo").innerHTML = height;
}
// });
});
}
else{
$(".homepage_main").css("height",h);
$("#myframe").css("height",height);
if(src.indexOf("http")==-1)
$("#myframe").attr("src","http://10.110.80.186/jcms/publish/zglh/zxggpc/"+src);
else
$("#myframe").attr("src",src);
}
}
</script>
总结:
这个需求有四个问题点,
一:iframe跨域请求并穿参数,
二:iframe子页面自适应高度,
三:图片高度在子页面无法获取,
四:父页面获取图片高度时用load方法当图片地址失效时报错
参考文章:
js和jquery如何获取(图片)真实的宽度和高度
iframe与主框架跨域相互访问方法