【问题标题】:Can an iframe check if itself is in viewport or not?iframe 可以检查自己是否在视口中吗?
【发布时间】:2022-02-11 02:18:14
【问题描述】:

我正在创建一个带有 HTML5 小视频的 iframe。除非iframe 在视口中,否则视频不应开始播放。

我注意到这并不像我想的那么简单,因为iframe 就像一个沙盒环境。 iframe 是否有可能知道它是否在视口中?

【问题讨论】:

    标签: javascript iframe viewport


    【解决方案1】:

    检查元素是否在视口中

    Here 你可以找到一个很好的实现来检查一个元素是否在视口中:

    function isInViewport(element) {
        const rect = element.getBoundingClientRect();
        return (
            rect.top >= 0 &&
            rect.left >= 0 &&
            rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
            rect.right <= (window.innerWidth || document.documentElement.clientWidth)
        );
    }
    

    到达父窗口

    iframe 中,您可以像这样访问父级window

    if (window.parent.isInViewport(document.querySelector('iframe'))) {
        //do something
    }
    

    (为了简单起见,我在父级window 中搜索第一个iframe,您可能需要更改选择器)

    然而,如果iframe 指向的页面与主页面指向的域相同,现代浏览器才允许这种通信。如果两个页面属于不同的域,那么现代浏览器会抛出一个CORSS error

    您可以在主页和加载到iframe 的页面之间使用messaging 作为替代方案,但为此需要主页的开发人员进行合作。

    【讨论】:

      【解决方案2】:

      如果 IFRAME 源属性“src”在同一个域中执行,则可以这样做,但如果 IFRAME 将 src 带到跨域,则需要从托管文件的服务器获得授权从您的域配置 CORS 接受。

      【讨论】:

        【解决方案3】:

        您可以使用 IntersectionObserver 来监控 iframe 是否进入视口。 如果你这样做,代码非常简单和干净。

        下面是一个快速示例,根据 iframe 是否在视口内来显示和关闭 youtube 视频。

        <!DOCTYPE html>
        <html lang="en">
        <head>
            <style>
                .container {
                  display: flex;
                  flex-direction: column;
                  gap: 1rem;
                  align-items: flex-start;
                }
        
                .box {
                  background-color:lightblue;
                  color: white;
                  font-size: 4rem;
                  text-align: center;
                  margin: auto;
                  height: 200px;
                  width: 300px;
                  border: 1px solid black;
                  border-radius: 0.25rem;
                  padding: 0.5rem;
                }
            </style>
            
        </head>
        <body>
            <div class="container">
                <div class="box">1</div>
                <div class="box">2</div>
                <div class="box">3</div>
                <div class="box">4</div>
                <div class="box">5</div>
        
                <div class="box" id="divFrame">
                    <iframe></iframe>
                </div>
        
                <div class="box">6</div>
                <div class="box">7</div>
                <div class="box">8</div>
                <div class="box">9</div>
                <div class="box">10</div>
            </div>
            
            <script>
                const iframeOserver = new IntersectionObserver((entries) => {
                    const iframe = entries[0].target.firstElementChild;
                    iframe.src = entries[0].isIntersecting ? "https://www.youtube.com/embed/tgbNymZ7vqY?autoplay=1&mute=1": "";
                    console.log("video " + (entries[0].isIntersecting ? "started" : "stopped"));
                }, { threshold: 0.5});
        
                iframeOserver.observe(document.getElementById("divFrame"));
        
            </script>
            
        </body>
        </html>
        

        在上面的例子中,我将相交的阈值设置为 50%(阈值:0.5)。您可以根据需要进行更改。

        有关 IntersectionObserver 的详细信息,请参阅以下链接: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-15
          • 2011-06-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多