Svelte 窗口元素打开:加载回调在移动 Safari 中未触发

问题描述 投票:0回答:1

我正在开发一个 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 中的初始页面加载时不会触发回调。

javascript mobile-safari svelte-3
1个回答
2
投票

据我所知,

<svelte:window />
可以让你监听
window
事件,所以你可以使用它,例如,通过
on:resize
来监听“调整大小”事件。 至于
on:load

(参见MDN的Window: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>
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.