1 回答
TA贡献1809条经验 获得超8个赞
事件侦听器和获取请求可能会发生一些潜在的情况。其他读者请注意,截至撰写本文时(2020 年 11 月),仅 Chrome/Chromium、Edge 和 Opera 支持 iframe 中的延迟加载。
这个答案针对的是还想使用延迟加载来动态加载内容的提问者。如果只关心发出单个网络请求,则可以通过 fetch 请求并src
通过 Blob 或数据 URI 或通过 或使用 Service Workers 设置 iframe 来完成srcdoc
(下面将对此进行探讨)。
添加事件侦听器之前可能加载的帧
您可以在声明框架后将事件侦听器添加到框架中,如果在评估脚本之前加载框架(如果已缓存,则可能会出现这种情况),这可能会产生问题。
contentWindow
通常,您可以通过或属性查看您的框架是否已加载contentDocument
,如果是,则在这些框架上运行初始化代码,但由于该框架是沙盒的,因此无法访问这些属性。相反,您可以做的是提前声明您的处理程序,然后在创建 iframe 时声明它:
async function loader(frame) {
console.log(frame.src);
// ...
}
<iframe src="frame.html" loading="lazy" sandbox="" onload="loader(this)"></iframe>
在获取请求中使用同源
根据 MDN,only-if-cached
只能在mode
设置为 时使用same-origin
,这在您的情况下应该没问题,因为您说框架是同源的。获取请求将类似于:
await fetch(src, { mode: 'same-origin', cache: 'only-if-cached' });
结果
main.html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<style>
.spacer {
height: 200vh;
background: lightgray;
text-align: center;
}
</style>
<script>
async function loader(frame) {
var sourceCodeElementId = frame.dataset.code;
var sourceCodeElement = document.getElementById(sourceCodeElementId);
var response = await fetch(frame.src, {
mode: 'same-origin',
cache: 'only-if-cached'
});
if (response.status === 504) {
// if it didn't load via cache, just get it normally
response = await fetch(frame.src);
}
var text = await response.text();
sourceCodeElement.textContent = text;
}
</script>
</head>
<body>
<div class="spacer">Scroll Down</div>
<iframe src="frame.html"
loading="lazy"
data-code="frame-source-code"
sandbox=""
onload="loader(this)">
</iframe>
<pre id="frame-source-code"></pre>
</body>
</html>
样本frame.html
<!doctype html>
<html>
Frame
</html>
可选/替代地使用 Service Worker
如果问题是围绕网络请求,您可以使用Service Workers,作为上述修复的替代方案或补充。让它们启动并运行需要一些工作,但它们可以让您更好地控制网络请求。缓存文件是一个常见的教程,因此如果您走这条路,您应该能够找到相当数量的资源。
添加回答
举报