所以我有一个包含iframe
元素的文档。
我的文档和iframe
有不同的来源。
我希望在文档中加载时,将此iframe
的内容看作是视差。
例如,文档如下所示:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>blah</p>
<p>blah</p>
<p>blah</p>
<p>blah</p>
<iframe src="parallax.html" width="200" height="200">
<p>blah</p>
<p>blah</p>
<p>blah</p>
</body>
</html>
parallax.html只包含适合窗口大小的图像。
我认为parallax.html应该有脚本来确定窗口相对于屏幕的位置并调整图像位置。我尝试了一些东西,例如:
document.body.scrollTop
,但它始终返回0 getBoundingClientRect()
个参数,但top
也返回0 这可能吗?我错过了什么吗?是的,我必须使用vanilla JS,没有jQuery或其他库。
答案 0 :(得分:1)
正如您所注意到的,跨域限制使得这有点棘手。您的父框架将无法访问内部变量或在其子框架中设置侦听器,反之亦然。它可以访问的属性非常有限,可在此处查看:https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Cross-origin_script_API_access
此外,我相信iframe中的document.body.scrollTop
和getBoundingClientRect()
相对于框架本身,就像框架是迷你窗口一样。您可能无法在iframe中访问所需的信息,但应该能够从父框架中获取该信息。
在跨源帧之间传递信息的传统方式是使用iframe.contentWindow.postmessage
。
在这种情况下,一个简单的实现是将您的滚动侦听器附加到父框架,该框架将消息发送到您的子框架。它看起来像这样:
在父文档:
中var iframeElement = document.getElementById('my-parallax'); // give your iframe this id
window.addEventListener('scroll', () => {
var rect = iframeElement.getBoundingClientRect();
var dataToSend = {
scrollY: window.scrollY,
left: rect.left, right: rect.right,
bottom: rect.bottom, top: rect.top
};
var targetOrigin = '*'; // can change this if you know it
iframeElement.contentWindow.postMessage(dataToSend, targetOrigin);
});
然后在 parallax.html :
window.addEventListener('message', function (e) {
var data = e.data;
if (e.source === window.parent) { // check if the sender was the parent
// use data.scrollY, data.top... etc. here
}
});
对这种方法的警告(以及一般的postMessage)是,不能保证iframe的UI将与父窗口同步更新。除非在任一帧上有大量计算,否则差异应该很小。据我所知,在使用跨域iframe时这是不可避免的。