Windows上的Google Chrome浏览器是否存在渲染iframe滚动条的问题?
我写了一个非常简单的代码来显示正在发生的事情(至少我在chrome 52.0.2743.82 m上):
<button>Toggle visibility</button>
<br />
<iframe scrolling="yes" seamless src="https://en.wikipedia.org/wiki/Lorem_ipsum" frameborder="0" style="width: 700px; height: 300px"></iframe>
<script type="text/javascript">
$("button").on("click", function() {
$("iframe").toggle();
});
</script>
加载页面时,iframe作为滚动条可见。
隐藏并显示iframe单击按钮。滚动条消失。
这个问题显然只发生在chrome。
任何人都有这样的经历吗?任何修复/解决方法?
答案 0 :(得分:4)
似乎更新Chrome 52.0.2743.82(http://googlechromereleases.blogspot.fr/2016/07/stable-channel-update.html)
出现了错误一种可能的解决方法是使用visibility
与[{1}}而不是position: absolute
的属性来显示或隐藏display
。
此商品存在chrome bug票证:https://bugs.chromium.org/p/chromium/issues/detail?id=641881
答案 1 :(得分:3)
我遇到了这个问题,使用visibility
代替display: none
并不是一个选择。
我的解决方法是每当我将iframe设置为再次可见时,在iframe中显示的文档的overflow: scroll
上设置<body>
。这似乎迫使滚动条再次出现在iframe上。然后,您可以将overflow
重置为旧值,滚动条将保留在iframe上。但是,您需要等待重新绘制才能重置overflow
,所以我将其置于延迟0的超时时间。
function showIframe(iframe) {
var iframeBody = iframe.contentDocument.body;
$(iframe).show();
var oldOverflow = iframeBody.css("overflow");
iframeBody.css("overflow", "scroll");
window.setTimeout(function () {
iframeBody.css("overflow", oldOverflow);
}, 0);
}
有一个&#34; flash&#34;但是,如果所讨论的iframe不需要滚动,则使用此解决方法的滚动条,因此在需要重新绘制的那个短暂时刻使用visibility
解决方法可能是值得的,以避免闪现。 / p>
答案 2 :(得分:1)
这是我为我正在构建的应用程序开发的解决方法。它在Foundation选项卡控件中有多个<iframe>
元素。
我使用MutationObserver
来观察<iframe>
的父元素(基金会div.tabs-content div.content
元素)何时变为active
,然后我切换{{1}文档的iframe
属性。运行时效果是不可思议的。
我原本想直接overflow
observe
,但是当iframe本身更改了<iframe>
属性时,没有引发任何DOM突变事件,我想因为技术上讲display
1}}值不是DOM结构的一部分。
这是我的代码(Vanilla.js,没有jQuery)。如果您在应用程序中使用,则需要将可见性检测代码替换为适用于您的文档的内容:
element.style
答案 3 :(得分:1)
对于给定的例子,你可以这样做:
$("iframe").toggle(1)
在我的情况下,它通过设置高度来工作:
$("iframe").css("height", "100%")
答案 4 :(得分:0)
我在Chrome上遇到类似问题,iframe嵌入到jQuery UI标签中。首次显示包含iframe的选项卡时,将显示滚动条。但是当我切换到另一个选项卡并返回到带有iframe的选项卡时,滚动条就会消失。这里提出的所有解决方案对我来说都不起作用。 以下是我为解决此问题所做的工作: 首先,我创建标签:
$("#mytabs").tabs();
然后我将一个函数绑定到事件&#34; tabsactivate&#34;我检查目标选项卡是否包含iframe。如果是这种情况,我会调用稍后描述的函数fixChromeScrollBar():
$("#mytabs").on("tabsactivate", function(event, ui) {
if ($(event.originalEvent.target).attr("href") == "#mytab-with-iframe") {
fixChromeScrollBar();
}
});
最后这里是函数fixChromeScrollBar(),它将iframe体的溢出样式属性(如上所述)设置为&#34; scroll&#34;或&#34; auto&#34;。我注意到,当我只定义&#34; auto&#34;或&#34;滚动&#34;然后,如果我切换到另一个选项卡并返回到iframe,我会丢失滚动条。维护它们的唯一方法是每次出现iframe时在两个值之间交替。这很奇怪,但它确实有效:
function fixChromeScrollBar() {
var iFrameBody = $("#myiframe").contents().find("body");
var originalOverflow = $(iFrameBody).css("overflow");
if (originalOverflow == "visible" || originalOverflow == "auto") {
$(iFrameBody).css("overflow", "scroll");
} else {
$(iFrameBody).css("overflow", "auto");
}
}
您可以注意到只有在切换到包含iframe的选项卡时才会调用此方法,因此如果您在此选项卡上多次单击而不切换到另一个选项卡,则此代码将仅在第一次执行时执行。
答案 5 :(得分:0)
显然设置src
刷新chrome中的iframe,对于给定的示例代码将是:
<script type="text/javascript">
$("button").on("click", function() {
$('iframe').toggle().attr('src', function(i, val) { return val; });
});
</script>
答案 6 :(得分:0)
我将戴的例子改编为我自己的React IFrame组件。我在选项卡面板中有一个iframe,它本身位于可折叠面板中。当其中任何一个被切换时,我强制iframe重新绘制。它运作得非常好。
private iframe: HTMLIFrameElement;
private displayObserver: MutationObserver;
componentDidMount() {
// Detect style attribute changes for the containing collapsible components
// If the display goes from 'none' to something else, then we need to redraw the iframe
// so we get the scrollbar back as it should be.
if (isChrome()) {
this.displayObserver = new MutationObserver(this.onContentMutated);
const options = { attributes: true, childList: false, characterData: false, subtree: false, attributeFilter: ['style'] };
const tabPanelAncestor = this.findAncestor(this.iframe, '.tab-panel-content');
if (tabPanelAncestor) {
this.displayObserver.observe(tabPanelAncestor, options);
}
const collapsibleAncestor = this.findAncestor(this.iframe, '.collapsible');
if (collapsibleAncestor) {
this.displayObserver.observe(collapsibleAncestor, options);
}
}
}
private readonly onContentMutated = (mutations: Array<MutationRecord>) => {
R.forEach( (mutation) => {
const targetElement = mutation.target as Element;
const style = targetElement.getAttribute('style');
if (style && !style.match(/display: none/)) {
this.iframe.contentWindow.location.reload(true);
}
}, mutations);
}
private readonly findAncestor = (element: HTMLElement, sel: string): Node | null => {
if (typeof element.closest === 'function') {
return element.closest(sel) || null;
}
let ancestor: HTMLElement | null = element;
while (ancestor) {
if (ancestor.matches(sel)) {
return ancestor;
}
ancestor = ancestor.parentElement;
}
return null;
}