可见性更改时,IFrame 滚动条在 chrome 上消失
Posted
技术标签:
【中文标题】可见性更改时,IFrame 滚动条在 chrome 上消失【英文标题】:IFrame scrollbar disappears on chrome when visibility changes 【发布时间】:2016-11-28 05:14:20 【问题描述】: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>
Plunker link to code
当页面加载时,iframe 作为它的滚动条是可见的。
点击按钮隐藏和显示 iframe。滚动条消失。
这个问题显然只发生在 chrome 中。
有人也遇到过这种情况吗?有任何修复/解决方法吗?
【问题讨论】:
Chrome 52.0.2743.82 似乎出现了该错误:googlechromereleases.blogspot.fr/2016/07/… 【参考方案1】:我将 Dai 的示例改编为我自己的 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;
【讨论】:
【参考方案2】:显然设置src
在chrome中刷新iframe,给定的示例代码将是:
<script type="text/javascript">
$("button").on("click", function()
$('iframe').toggle().attr('src', function(i, val) return val; );
);
</script>
【讨论】:
想解释一下它为什么有效,而不是只发布代码?【参考方案3】:我在 Chrome 上遇到了类似的问题,其中 iframe 嵌入到 jQuery UI 选项卡中。首次显示包含 iframe 的选项卡时,会出现滚动条。但是当我切换到另一个选项卡并返回到带有 iframe 的选项卡时,滚动条就会消失。这里提出的所有解决方案都不适合我。 这是我为解决此问题所做的工作: 首先,我创建标签:
$("#mytabs").tabs();
然后我将一个函数绑定到事件“tabsactivate”并检查目标选项卡是否是包含 iframe 的选项卡。如果是这种情况,我将调用稍后描述的函数 fixChromeScrollBar():
$("#mytabs").on("tabsactivate", function(event, ui)
if ($(event.originalEvent.target).attr("href") == "#mytab-with-iframe")
fixChromeScrollBar();
);
最后是函数 fixChromeScrollBar(),它将 iframe 主体的溢出样式属性(如前所述)设置为“滚动”或“自动”。我注意到,当我只定义“自动”或“滚动”值时,如果我切换到另一个选项卡并返回 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 的选项卡时才会调用此方法,因此如果您在此选项卡上多次单击而不切换到另一个选项卡,则只会在第一次执行此代码。
【讨论】:
【参考方案4】:对于给定的示例,您可以这样做:$("iframe").toggle(1)
在我的情况下,它通过设置高度来工作:$("iframe").css("height", "100%")
【讨论】:
【参考方案5】:Chrome 52.0.2743.82 (http://googlechromereleases.blogspot.fr/2016/07/stable-channel-update.html) 更新似乎出现了这个错误
一种可能的解决方法是使用属性visibility
和position: absolute
而不是display
来显示或隐藏iframe
。
此项目存在 chrome bug 票证:https://bugs.chromium.org/p/chromium/issues/detail?id=641881
【讨论】:
关于这个的问题,显示属性是至关重要的,没有它我的网站就无法工作,有什么办法可以解决这个错误?还有关于谷歌可能修复的任何信息吗?他们知道吗? 我可以在 Chrome 54 中重现此问题,但我在 bugs.chromium.org 中找不到任何报告的错误 - 它是否存在或者我应该提交一个新错误?【参考方案6】:这是我为正在构建的应用程序开发的解决方法。它在 Foundation 选项卡控件中有多个 <iframe>
元素。
我使用MutationObserver
观察<iframe>
的父元素(基础div.tabs-content div.content
元素)何时变为active
,然后切换iframe
的文档的overflow
属性。运行时效果难以察觉。
我最初想直接observe
<iframe>
,但是当 iframe 本身更改 display
属性时没有引发 DOM 突变事件,我猜是因为从技术上讲 element.style
值不是 DOM 结构的一部分正确的。
这是我的代码(Vanilla.js,没有 jQuery)。如果您在您的应用程序中使用,您需要将我的可见性检测代码替换为适用于您的文档的代码:
window.addEventListener('DOMContentLoaded', function(e)
var observer = new MutationObserver( onContentMutated );
var options = attributes: true, childList: false, characterData: false, subtree: false, attributeFilter: ['class'] ;
var iframeContainers = document.querySelectorAll('.tabs-content .content');
for(var i = 0; i < iframeContainers.length; i++)
observer.observe( iframeContainers[i], options );
);
function onContentMutated(mutations)
for(var i = 0; i < mutations.length; i++)
var m = mutations[i];
var thisIsNowAnActiveTab = m.target.classList.contains('active');
if( thisIsNowAnActiveTab )
// get the corresponding iframe and fiddle with its DOM
var iframes = m.target.getElementsByTagName("iframe");
if( iframes.length == 0 ) continue;
var iframe = iframes[0];
iframe.contentWindow.document.documentElement.style.overflow = 'hidden';
// the timeout is to trigger Chrome to recompute the necessity of the scrollbars, which makes them visible again. Because the timeout period is 0 there should be no visible change to users.
setTimeout( function(s)
s.overflow = 'auto';
, 0, iframe.contentWindow.document.documentElement.style );
console.log( m.type );
【讨论】:
【参考方案7】:我遇到过这个问题,并且不能使用 visibility
代替 display: none
。
我的解决方法是在 iframe 中显示的文档的 <body>
上设置 overflow: scroll
,每当我将 iframe 设置为再次可见时。这似乎迫使滚动条再次出现在 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);
如果有问题的 iframe 不需要滚动,则此解决方法会出现滚动条的“闪烁”,因此在需要重绘的短暂时刻使用 visibility
解决方法可能是值得的,避开闪光灯。
【讨论】:
以上是关于可见性更改时,IFrame 滚动条在 chrome 上消失的主要内容,如果未能解决你的问题,请参考以下文章