Chrome下, iframe中PageUp时导致父/祖先元素显示错位
问题
实际工作中发现, 在Chrome浏览器下, 在iframe
中按PageUp键, 会导致父元素显示错位. 如下图:
此时获取父元素的scrollTop
, 值为1
.
以下是实例代码:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Editor Demo</title>
<link rel="stylesheet" href="http://necolas.github.com/normalize.css/3.0.1/normalize.css" />
<style>
* {
padding: 0;
margin: 0;
}
#wrapper{
margin: 20px;
width: 600px;
height: 400px;
border: 1px solid #CCC;
background-color: #FF0;
/**** NOTE *****/
overflow: hidden;
}
iframe {
width: 100%;
border: 0;
}
</style>
</head>
<body>
<div id="wrapper">
</div>
<script type="text/javascript">
var wrapper = document.getElementById('wrapper'),
iframe = document.createElement('iframe');
wrapper.appendChild(iframe);
window.setTimeout(function () {
var doc = iframe.contentDocument,
html = '<article class="editor-area" spellcheck="false">' +
'<p>但是极力反对快速减肥第三方的时间发生的大街上反垄断法时间的顺丰快递舒服fd</p>' +
'<div>' +
'<img src="http://img0.fspcdn.com/pictures/796/22/79622.jpg">' +
'<br></div>' +
'<div>sfjdfsldfsjdfs</div>' +
'<div><br></div>' +
'</article>';
doc.body.innerHTML = html;
doc.body.style.backgroundColor="#F00";
doc.getElementsByTagName('article')[0].contentEditable = true;
iframe.style.height = '400px';
}, 1000);
</script>
</body>
</html>
触发以上问题需要注意以下几点:
- 必须在Windows + Chrome环境下; mac + Chrome, Windows + Firefox下未发现该问题
- iframe的父元素或者祖先元素必须设置
overflow
为hidden
,auto
等, 不可设置为visible
(默认也是visible
). 但iframe的父/祖父元素需要overflow: hidden
的情况. - iframe的高度设置必须与与父元素的高度一致.
分析问题
- 网上搜搜是否有遇到类似问题, 无果.
- 原工程中有很多的JavaScript代码, 将JavaScript移除, 生成以上示例类似的代码, 排除JavaScript的问题.
- 将示例类似代码放在Firefox下, 发现没有问题.
如何解决呢? 没有思路了
解决问题
无奈之下, 挨个设置iframe
相关的属性(参阅: HTML <iframe> Tag 中 Attributes一节), 当设置到seamless
时, 发现起作用了, 解决了以上问题.
w3schools上有关seamless
的解释是:
The seamless attribute is a boolean attribute.
When present, it specifies that the <iframe> should look like it is a part of the containing document (no borders or scrollbars).
优化
搜索了iframe seamless
, 发现seamless
并不是w3schools上描述得那么简单(参阅SEAMLESS IFRAMES -- THE FUTURE, TODAY!). 能否不设置seamless
呢?
在Chrome调试工具中, seamless
的iframe
有以下特殊之处:
iframe[seamless] {
display: block;
}
iframe:not([seamless]) {
border: 2px inset;
border-image-source: initial;
border-image-slice: initial;
border-image-width: initial;
border-image-outset: initial;
border-image-repeat: initial;
}
是否只要设置display
为block
就OK了呢? 经过实验, 是OK的.
原来iframe
默认的display
为inline
!!!
总结
终极解决方案
iframe {
border: none;
display: block;
}