我正在开发一个 Svelte 和 Sapper 静态站点,并将其导出并上传到服务器。
rollup.config.js
和 package.json
与 Github 上的 sapper-template 相同,对 package.json
稍作修改,以避免在 mac 上开发时出现 .DS_store 问题:
"scripts": {
"dev": "yarn dsstore:delete && sapper dev",
"build": "yarn dsstore:delete && sapper build --legacy",
"export": "yarn dsstore:delete && sapper export --legacy",
"start": "node __sapper__/build",
"dsstore:delete": "find . -name \".DS_Store\" -delete"
}
我在一个简洁的组件中使用以下代码,该代码在主页上重复了大约十次。这是一个以高质量摄影为主要内容的网站,因此我加载了一张厚重的图像作为组件的背景图像。为了平滑图像加载体验,我首先在背景中加载一个非常亮的占位符图像,然后根据窗口大小,在顶部加载两个不同大小的背景图像之一:
<script>
export let project;
let { id, src, src_small } = project;
let el;
let breakpointCondition = "(max-width: 1000px)";
let view;
let imageSrc;
const checkView = (e) => {
console.log(document);
el = document.getElementById(id);
console.log(el);
view = window.matchMedia(breakpointCondition);
if (view.matches) {
imageSrc = src_small;
} else {
imageSrc = src;
}
el.style.backgroundImage = `url(${imageSrc}), url('images/placeholder.png')`;
}
</script>
<svelte:window on:load={checkView} on:resize={checkView} />
<section id={id} >
...
<section>
<style>
section {
background-image: url('/images/placeholder.png');
}
</style>
此代码在桌面浏览器上按预期工作。页面加载后,细长的窗口元素变得可用,我可以查询它以加载适当的背景图像。在 iOS 浏览器(移动版 Safari、Chrome 和 Firefox)上,当我导航到页面时,来自 javascript 的背景图像不会加载,但如果我刷新页面,它们就会加载。
我尝试替换:
<svelte:window on:load={console.log('load')} on:resize={console.log('resize')} />
并发现 window.onload 和 window.onresize 事件在页面加载时在桌面和移动浏览器上触发。奇怪的是,当我在页面加载后调整窗口大小时,没有日志出现,但
window.matchMedia
方法似乎继续执行其工作,并且图像交换发生在适当的断点处。
当我将日志放在
checkView
回调函数的开头时,我发现虽然 onload
事件正在触发,但当页面首次在 iOS 移动浏览器上加载时,该函数不会触发。当我在 ios 浏览器上重新加载页面时,回调函数会触发,我会得到预期的结果。
为什么会发生这种情况以及我该如何解决它?此方法在桌面上效果很好。
更新:使用
onMount
在页面加载时触发checkView
并且
<svelte:window on:resize={checkView} />
当调整窗口大小时有效。问题仍然悬而未决,以防有人知道原因的答案
<svelte:window on:load={checkView}>
在移动 Safari 中的初始页面加载时不会触发回调。
据我所知,
<svelte:window />
可以让你监听window
事件,所以你可以使用它,例如,通过on:resize
来监听“调整大小”事件。
至于on:load
:
加载整个页面(包括样式表和图像等所有依赖资源)时会触发加载事件。这与 DOMContentLoaded 形成对比,DOMContentLoaded 在页面 DOM 加载后立即触发,无需等待资源完成加载。
因此,如果页面已加载并且加载事件已被触发,则监听此事件是多余的,并且回调将永远不会调用。 当页面真正完成加载时检查您的代码(index.html?)
如果您想确保特定 Svelte 组件中的 DOM 元素完成渲染,Svelte 建议使用其
onMount(() => {})
回调:
<script>
export let project;
let { id, src, src_small } = project;
import { onMount } from 'svelte';
let el;
let breakpointCondition = "(max-width: 1000px)";
let view;
let imageSrc;
onMount(() => {
console.log(document);
el = document.getElementById(id);
console.log(el);
view = window.matchMedia(breakpointCondition);
if (view.matches) {
imageSrc = src_small;
} else {
imageSrc = src;
}
el.style.backgroundImage = `url(${imageSrc}), url('images/placeholder.png')`;
})
</script>
<section id={id} >
...
</section>
<style>
section {
background-image: url('/images/placeholder.png');
}
</style>