iframe可以检查自己是否在视窗中吗?



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

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

检查元素是否在视口中

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

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错误。

您可以在主页和加载到iframe中的页面之间设置消息传递,但为此目的,主页的开发人员需要合作。

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

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

下面是一个基于iframe是否在viewport内显示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

相关内容

最新更新