问题:在iOS上一个页面通过iframe嵌套一个页面,内容页面中一个显示在页面底部的元素显示不出来,这个元素的 position 为 fixed 。
原因:因为 iOS 下的 Safari 的 IFrame 的高度会根据页面的内容自适应造成了 IFrame 的高度过高(即iframe的高度>屏幕的高度)。这个元素的 position 为 fixed显示在了屏幕外面,导致iframe下position:fixed失效,
重现 Bug
简单粗暴,直接上码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<div>
<style>
iframe {
border: 1px solid #ccc;
width: 100%;
height: 300px;
}
</style>
<iframe frameborder="0" src="content.html"></iframe>
</div>
</body>
</html>
内容页的文件名为 content.html,内容页代码如下:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<script type="text/javascript">
var addcontent = function() {
document.body.appendChild(document.getElementById('test').cloneNode(true));
};
</script>
<button onclick="addcontent()">Add content</button>
<div id="test">
<p>test content</p>
<p>test content</p>
<p>test content</p>
<p>test content</p>
<p>test content</p>
<p>test content</p>
</div>
</body>
</html
重现这个问题相当简单,使用 苹果打开,点击 Add content 按钮,虽然定义了IFrame 的高度为300,但是IFrame 的高度会自动增加。
解决办法
既然 IFrame 的高度是由内容页面的 body 的高度决定的,那就想办法让内容页面的 body 的高度永远不会超过 window 的高度就不会触发这个问题了。
那就把内容页面中的内容移动到一个绝对定位的元素里面,这个绝对定位的元素显示为全屏。
修正过的内容页面的内容如下:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<style>
#content-wrapper {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
overflow: hidden;
}
</style>
<script type="text/javascript">
var addcontent = function() {
document.getElementById('content-wrapper').appendChild(document.getElementById('test').cloneNode(true));
};
</script>
<div id="content-wrapper">
<button onclick="addcontent()">Add content</button>
<div id="test">
<p>test content</p>
<p>test content</p>
<p>test content</p>
<p>test content</p>
<p>test content</p>
<p>test content</p>
</div>
</div>
</body>
</html>
注意:移动端使用 IFrame 不是一个很常见的做法。