2016-07-24 46 views
7

Windows上的Google Chrome在呈現iframe滾動條時出現問題嗎?當可見性發生變化時,IFrame滾動條在Chrome上消失

我寫了一個非常簡單的代碼來顯示所發生的事情(至少我在Chrome 52.0.2743.82米):

<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中。

任何人都在遇到這種情況?任何修補程序/解決方法?

+0

看來,錯誤出現在Chrome 52.0.2743.82:http://googlechromereleases.blogspot.fr/2016/07/stable-channel-update.html – lepix

回答

4

看來,錯誤出現了更新的Chrome 52.0.2743.82(http://googlechromereleases.blogspot.fr/2016/07/stable-channel-update.html

一個可能的解決方法是使用屬性visibilityposition: absolute代替display顯示或隱藏iframe

Chrome錯誤標籤存在爲這個項目:https://bugs.chromium.org/p/chromium/issues/detail?id=641881

+0

對於這個問題,在顯示屬性是至關重要的,我網站不能沒有它,任何替代方法來解決這個錯誤?也有任何有關谷歌可能的修復信息?他們知道嗎? –

+0

我可以在Chrome 54中重現此問題,但在https://bugs.chromium.org中找不到任何已報告的錯誤 - 它是否存在或是否應提交新的錯誤? – Dai

-2

添加

iframe { overflow-y: scroll; } 

你的CSS

3

我有這個問題,並使用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解決方法可能是值得的,以避免閃光。

1

這是我爲我正在構建的應用程序開發的解決方法。它在基礎選項卡控件中具有多個元素。

我用MutationObserver觀察時的父元素(一個基金會div.tabs-content div.content元素)變得active,然後我切換iframe的文檔的overflow財產。運行時效果是不可思議的。

我本來想observe的直接,但是因爲從技術上來講element.style值沒有DOM突變事件時的iframe本身已經改變display財產提出,我想是不是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); 
    } 
} 
1

對於給定的例子,你可以這樣做:
$("iframe").toggle(1)

在我情況下,它的工作由設後的高度:
$("iframe").css("height", "100%")

0

我有一個類似的問題在Chrome中嵌入一個jQuery UI選項卡中的iframe。第一次顯示包含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體的溢出style屬性(前面已經說了),要麼「滾動「或」自動「。我注意到,當我只定義「auto」或「scroll」值時,如果我切換到另一個選項卡並返回到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標籤,只調用會第一次執行。

0

顯然設置src刷新的iframe在Chrome中,對於給定的示例代碼將是:

<script type="text/javascript"> 
    $("button").on("click", function() { 
     $('iframe').toggle().attr('src', function(i, val) { return val; }); 
    }); 
</script> 
+0

小心解釋它爲什麼會起作用,而不僅僅是發佈代碼? –

0

我適應我自己陣營的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; 
} 
相關問題