简体   繁体   English

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

[英]Svelte window element on:load callback not firing in mobile Safari

I am working on a Svelte and Sapper static site which I am exporting and uploading to a server.我正在开发一个 Svelte 和 Sapper static 站点,我正在导出并上传到服务器。 The rollup.config.js and package.json are as in the sapper-template on Github with a slight modification to the package.json to avoid issues with.DS_store when developing on mac: The rollup.config.js and package.json are as in the sapper-template on Github with a slight modification to the package.json to avoid issues with.DS_store when developing on mac:

"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"
}

I am using the following code in a svelte component that is repeated about ten times on the home page.我在主页上重复大约十次的苗条组件中使用以下代码。 This is a site where high-quality photography is the main content, so I am loading a heavy image as a background-image of the component.这是一个以高品质摄影为主要内容的网站,因此我正在加载重图像作为组件的背景图像。 To smooth the image loading experience, I am first loading a very light placeholder image in the background, and then, based on the window size, loading one of two different sized background-images on top:为了平滑图像加载体验,我首先在背景中加载一个非常轻的占位符图像,然后根据 window 大小,在顶部加载两个不同大小的背景图像之一:

<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>

This code works as expected on desktop browsers.此代码在桌面浏览器上按预期工作。 Once the page loads, the svelte window element becomes available and I can query it in order to load the appropriate background image.页面加载后,纤细的 window 元素变为可用,我可以查询它以加载适当的背景图像。 On ios browsers (mobile Safari, Chrome, and Firefox), the background images from the javascript do not load when I navigate to the page, though if I refresh the page, they do.在 ios 浏览器(移动 Safari、Chrome 和 Firefox)上,当我导航到页面时,不会加载来自 javascript 的背景图像,但如果我刷新页面,它们会加载。

I tried substituting:我尝试替换:

<svelte:window on:load={console.log('load')} on:resize={console.log('resize')} />

and found that the window.onload and window.onresize events are firing on both desktop and mobile browsers on page load.并发现 window.onload 和 window.onresize 事件在页面加载时在桌面和移动浏览器上触发。 Strangely, no logs appear when I resize the window after the page loads, but the window.matchMedia method appears to continue doing its job and the image swap happens at the appropriate breakpoint.奇怪的是,当我在页面加载后调整 window 的大小时,没有出现任何日志,但是window.matchMedia方法似乎继续完成它的工作,并且图像交换发生在适当的断点处。

When I place logs in the beginning of the checkView callback function, I see that while the onload event is firing, the function is not firing when the page first loads on ios mobile browsers.当我将日志放在checkView回调 function 的开头时,我看到在触发onload事件时,当页面首次在 Z9E304D4E8DF1B74CFA009913198 移动浏览器上加载时,function 没有触发When I reload the page on ios browsers, the callback function fires and I get the expected results.当我在 ios 浏览器上重新加载页面时,回调 function 触发,我得到了预期的结果。

Why might this be happening and how might I work around it?为什么会发生这种情况,我该如何解决? This method works well on desktop.此方法在桌面上运行良好。

UPDATE: Using onMount to fire checkView when the page loads and更新:当页面加载时使用onMount触发checkView

<svelte:window on:resize={checkView} />

when the window is resized works.当 window 调整大小时工作。 Question is still open in case anyone has an answer for why问题仍然悬而未决,以防有人回答原因

<svelte:window on:load={checkView}>

won't fire the callback on initial page load in mobile Safari.在移动 Safari 中的初始页面加载时不会触发回调。

As far as I know, <svelte:window /> lets you listen to window events, so you can use it, for instance, by on:resize to listen to the 'resize' events.据我所知, <svelte:window />可以让您收听window事件,因此您可以使用它,例如,通过on:resize来收听“调整大小”事件。 As for on:load :至于on:load

(see MDN's Window: load event:) (参见 MDN 的 Window:加载事件:)

The load event is fired when the whole page has loaded, including all dependent resources such as stylesheets and images.加载整个页面时会触发 load 事件,包括所有相关资源,例如样式表和图像。 This is in contrast to DOMContentLoaded, which is fired as soon as the page DOM has been loaded, without waiting for resources to finish loading.这与 DOMContentLoaded 不同,后者在页面 DOM 加载后立即触发,无需等待资源完成加载。

So, if the page is loaded and the load event has already been fired, listening to this event is redundant and the callback will never call.所以,如果页面被加载并且 load 事件已经被触发,那么监听这个事件是多余的并且回调永远不会调用。 Check in your code when the page is really done loading (index.html?)当页面真正完成加载时检查您的代码(index.html?)

If you want to be sure the DOM elements in a specific Svelte component are done rendering, Svelte suggests their onMount(() => {}) callback:如果您想确保特定 Svelte 组件中的 DOM 元素已完成渲染,Svelte 建议使用其onMount(() => {})回调:

<script>
    export let project;
    let { id, src, src_small } = project;

    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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM