场景介绍
我们的的项目比较宠大,集成多个大模块,大模块下面又分多个小模块 。项目是协同开发,有多个项目组,每一个项目是独立运行开发的。系统集成在一个总端,总端进行登录管理,主题框架、路由管理。页面结构上中下,上是主模块导航,中又分为左导航,右内容展示。现在项目进行重构 ,内容展示是iframe。原来是用c#进行的开发,现在实现前后端分离,前端使用vue element-ui。老的页面alert、confirm、在iframe 触发时在窗体正中上方展示,现如今如果在页面滚动比较底部的时候 alert 是相对于iframe的窗体居中显示的 ,在主题框架外部进行了iframe高度设置,会随着外部的滚动进行页面展示。
解决办法
我们就用2个页面进行场景模拟,父页面和子页面 ,子页面是通过父页面iframe 引起来的。
父页面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
padding: 0;
margin: 0;
}
.main{
display: flex;
}
.left{
width: 200px;
background: #ccc;
height: 300px;
}
#iframe{
width: 100%;
}
</style>
<script>
function callback(){
var iframe = document.getElementById('iframe');
var height = iframe.contentDocument.body.scrollHeight
iframe.style.height = height +"px"
console.log(height)
}
window.onload=function(){
callback()
}
// document.onload=function(){
// callback()
// }
</script>
</head>
<body>
<div style="height:200px;background:blue"></div>
<div class="main">
<div class="left"></div>
<iframe id="iframe" src="./son.html" ></iframe>
</div>
</body>
</html>
子页面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
padding: 0;
margin: 0;
}
.box{
background: red;
height: 2000px;
overflow: hidden;
}
.btn1{
display: block;
margin-top: 500px;
}
.btn2{
display: block;
margin-top: 1400px;
}
#mask{
width: 100px;
height: 100px;
position: fixed;
left: 50%;
background: yellow;
transform: translateX(-50%);
display: none;
}
</style>
<script>
window.onload = function(){
var haoroomsId = document.getElementById('haorooms');
var MutationObserver = window.MutationObserver || window.webkitMutationObserver || window.MozMutationObserver;
var recordHeight = 0;
var mutationObserver = new MutationObserver(function (mutations) {
console.log(mutations);
//给iframe 设置高度
top.window.callback()
})
mutationObserver.observe(haoroomsId, {
childList: true, // 子节点的变动(新增、删除或者更改)
attributes: true, // 属性的变动
characterData: true, // 节点内容或节点文本的变动
subtree: true // 是否将观察器应用于该节点的所有后代节点
})
}
function showBox(){
debugger
let mask = document.getElementById('mask');
mask.style.display="block"
var topx = top.window.pageYOffset
console.log(topx)
mask.style.top=topx+"px"
top.window.document.body.style.overflowY="hidden"
}
function closeBox(){
let mask = document.getElementById('mask');
mask.style.display="none"
top.window.document.body.style.overflowY="auto"
}
var init=10
function add(){
debugger
var bottom = document.getElementById('bottom')
init=init+10
bottom.style.height=init+'px'
}
</script>
</head>
<body id="haorooms">
<div class="box">
<button class="btn0" onclick="add()">btn100</button>
<button class="btn" onclick="showBox()">btn0</button>
<button class="btn1" onclick="showBox()">btn1</button>
<button class="btn2" onclick="showBox()">btn2</button>
</div>
<div id="bottom"></div>
<div id="mask">
<button onclick="closeBox()">close</button>
</div>
</body>
</html>
btn0,btn1,btn2 都是触发弹层展示的,在点击触发showBox的时候获取到当前滚动条的位置 ,然后给结应的弹层设置top 高度 ,这样就会随着滚动条的滚动正常的显示弹窗了。获取iframe 外层滚动条用top.window.pageYOffset 获取 ,当然这个对于高版本浏览器没有问题,为了使用兼容性 top.window.pageYOffset || top.window.document.body.scrollTop || top.window.document.documentElement.scrollTop