公司的后台系统使用了iframe布局,二期iframe内外页面分别属于两个不同的域效果图如下:
然后这个页面里面有个坑爹的模态对话框,像下面这样
外层页面有个坑爹的滚动条,导致滚动条一滚动内层页面的模态对话框就不能在整个显示器垂直居中了,如果两个页面是同域的也还好办外层滚动条滚动的时候去调用内层页面的回调函数重新设置模态对话框的位置,可现在两个页面还是跨域的,上网找了跨域的相关方案,想到一个办法。
方案1:外层页面再放一个iframe 就简称 页面c吧,然后外层页面滚动条发生滚动的时候重新加载页面c并把滚动条的位置当做参数传递给页面c 部分核心代码:
<div style="width: 0px; height: 0px;">
<iframe id="cross-domain" style="display: none;" >
iframe>
div>
<script>
var url="http://{$ktvmeDestineUrl}/Public/html/cross-domain.html";
window.onscroll = function(){
var t = document.documentElement.scrollTop || document.body.scrollTop;
var path=url+"?t="+t;
$("#cross-domain").attr('src',path);
}
script>
然后在c页面里面取出参数由于c页面和内层页面是同一个域所以不存在跨域问题可以调用内层页面的回调函数通知外层页面滚动条的位置 c页面代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>title>
head>
<body>
跨域支持
<script
window.onload = function(){
var text = window.location.href.split('=')[1]
parent.frames["main"].scrollcallback(text);
}
script>
body>
html>
内层页面代码:
function scrollcallback(t){
$("#tsbox").animate({'margin-top':t+'px'},0);
}
内层页面的回调函数会在外层页面滚动条滚动的时候被调用参数t为外层页面滚动条到页面顶部的距离。
这个方案有个非常大的缺点,我们再来回顾下步骤
1、在页面滚动条变动的时候通过修改src属性调用页面c(和内层页面同域)传入参数
2、页面c装载完毕之后取出参数,调用内层页面的回调函数
相信有经验的朋友已经看出这个过程存在的巨大问题,就是每次调用的过程页面都会重新加载,从而产生延迟,而且给服务端会造成额外的压力,外层页面的滚动条滚动和内层对话框的位置也不同步,经过苦思冥想终于想出方案2完美解决了该问题
方案2:大致思路相同利用操控一个和内层页面同域的c页面操控内层页面,不过不通过控制src属性而是通过控制c页面所在 iframe的宽度(或者高度)去触发c页面的onresize事件进而操作内层页面
外层页面代码:
<!--用于跨域操作的iframe-->
<div style="width: 0px; height: 0px; overflow: hidden;">
<iframe src="http://{$ktvmeDestineUrl}/Public/html/cross-domain.html" id="cross-domain" style=" width: 0px;" >
</iframe>
</div>
<script>
window.onscroll = function(){
var t = document.documentElement.scrollTop || document.body.scrollTop;
$("#cross-domain").width(t);
}
</script>
c页面代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!--跨域支持-->
<script>
window.onresize=function(){
try{
parent.frames["main"].scrollcallback(window.innerWidth || document.body.clientWidth);
}catch (e){
}
};
</script>
</body>
</html>
内层页面代码还是不动,这样内层页面还外层页面的通讯不必通过服务器都在本地发生,大大提高了跨域调用的速度