首页 > 解决方案 > 具有应用程序/pdf 的对象在父元素的可见性更改时中断

问题描述

给定以下代码段:

<script>
    function show(id)
    {
        for(let i = 1; i<=3; i++)
        {
            const elem = document.getElementById("pdf-box-"+i);
            if(i === id) elem.style = "";
            else elem.style = "display:none";
        }
    }
</script>

<button onclick="show(1)">Show #1</button><br/>
<button onclick="show(2)">Show #2</button><br/>
<button onclick="show(3)">Show #3</button><br/>

<div id="pdf-box-1" style="display:none">
  <object data="https://maio290.de/lorem.pdf" type="application/pdf"  height="800" width="95%"></object>
</div>

<div id="pdf-box-2" style="display:none">
  <object data="https://maio290.de/lorem.pdf" type="application/pdf"  height="800" width="95%"></object>
</div>

<div id="pdf-box-3" style="display:none">
  <object data="https://maio290.de/lorem.pdf" type="application/pdf"  height="800" width="95%"></object>
</div>

由于这似乎在 Stackblitz 中不起作用 - 您可以点击此处自行尝试。

我可以很好地显示所有 PDF - 但只能显示一次。当我取消隐藏父元素时,对象无法正确呈现。当前基于 Chromium 的浏览器(已测试 Microsoft Edge 和 Chrome)中存在此错误- Firefox 似乎没有受到影响。当我调整窗口大小时,PDF 再次显示。

有没有人遇到过这个错误并找到了可行的解决方案?我遇到这个问题的应用程序实际上是基于带有 Primefaces 的 JSF。因此,我无法更改它们的逻辑以正确隐藏/显示元素。我还想保留object用于显示 PDF 的标签,并且只使用iframeusing staticpdf.js作为最后的手段。

标签: htmlpdf

解决方案


所以对于那些想知道如何绕过这个问题的人来说:强制浏览器重新渲染的最简单方法是添加边距值。如果这不适用,您可以摆弄其他 CSS 属性。

我最终为 JSF 和 Primefaces 使用了以下代码:

                <ui:fragment rendered="#{request.getHeader('user-agent').contains('Chrome')}">
                    <script>
                            function fixChromePDFBug()
                            {
                                const documentTabParent = document.getElementById("form:documentFiles");
                                documentTabParent.removeAttribute("style");
                                documentTabParent.style = "margin: "+Math.random()+"px";
                            }
                            
                            function execDelayed()
                            {
                                setTimeout(fixChromePDFBug, 300);
                            }                           
                                            
                            
                            function addListenerToTab()
                            {
                                const documentTabParent = document.getElementById("form:documentFiles");
                                const anchors = documentTabParent.getElementsByTagName("a");
                                
                                for(let anchor of anchors)
                                {
                                    anchor.addEventListener("click",execDelayed, false);
                                }
                                
                            }

                            addListenerToTab();
                    </script>
                </ui:fragment>  

推荐阅读