首页 > 解决方案 > 加载 CSS 文件时的加载器

问题描述

我正在创建一个网站,我想在其中创建一个加载器。但是我将链接标签放在头部,除非加载大样式表,否则它不会显示加载器。

如果我打开 firefox/chrome 的开发者工具 -> 响应式视图,并启用网络选项卡 -> 模拟 2G 速度,我可以清楚地看到样式表正在加载,然后显示加载器动画,然后加载脚本。但是我有很大的样式表,甚至在加载样式表之前就想显示动画徽标。

例如:[加载器在这里不突出,这对 html 文件最有效]

<head>
    <style>
        html, body { margin: 0 ; padding: 0 }

        #loader-head {
            height: 100vh ;
            width: 100% ;
            display: flex ;
            justify-content: center ;
            align-items: center ;
            flex-direction: column ;
            z-index: 10000 ;
            position: fixed ;
            top: 0 ;
            left: 0 ;
            background-color: #25DD84 ;
        }

        #loader-head > #loader { width: 150px ; height: 150px ; position: relative }

        #loader-head > #loader > .loaders {
            position: absolute ;
            width: 50px ;
            height: 50px ;
            background-color: #fff ;
            border-radius: 4px ;
            box-shadow: 0 0 6px #fff ;
            animation: loaderChase 2s ease infinite ;
        }

        #loader-head p {
            font-size: 48px ;
            position: relative ;
            color: #fff ;
            overflow: hidden ;
            text-shadow: 0 0 6px #fff ;
        }

        #loader-head p::before {
            content: 'Loading...' ;
            position: absolute ;
            top: 0 ;
            left: 0 ;
            width: 100% ;
            background: linear-gradient(45deg, #fff, #fff, #fff, #ff5, #f55, #55f) ;
            background-size: 200% ;
            background-clip: text ;
            -webkit-background-clip: text ;
            color: transparent ;
            animation: loaderTextAnim 1s ease infinite 0.75s ;
        }

        @keyframes loaderChase {
            0% { top: 0 ; left: 0 }
            12.5%, 25% { top: 0 ; left: 50% }
            37.5%, 50% { top: 50% ; left: 50% }
            62.5%, 75% { top: 50% ; left: 0 }
            87.5%, 100% { top: 0 ; left: 0 }
        }

        @keyframes loaderTextAnim {
            0% { background-position: 200% }
            90%, 100% { background-position: 0% }
        }
    </style>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
</head>

<body>
    <div id="loader-head">
        <div id="loader">
            <div class="loaders" style="animation-delay: 200ms"></div>
            <div class="loaders" style="animation-delay: 900ms"></div>
            <div class="loaders" style="animation-delay: 1600ms"></div>
        </div>
        <p>Loading...</p>
    </div>

    Hello!

    <script>
        window.onload = function() {
            document.getElementById('loader-head').remove()
        }
    </script>
</body>

但是,如果我将链接标签放在标签内,则会显示动画:

<head>
    <style>
        html, body { margin: 0 ; padding: 0 }

        #loader-head {
            height: 100vh ;
            width: 100% ;
            display: flex ;
            justify-content: center ;
            align-items: center ;
            flex-direction: column ;
            z-index: 10000 ;
            position: fixed ;
            top: 0 ;
            left: 0 ;
            background-color: #25DD84 ;
        }

        #loader-head > #loader { width: 150px ; height: 150px ; position: relative }

        #loader-head > #loader > .loaders {
            position: absolute ;
            width: 50px ;
            height: 50px ;
            background-color: #fff ;
            border-radius: 4px ;
            box-shadow: 0 0 6px #fff ;
            animation: loaderChase 2s ease infinite ;
        }

        #loader-head p {
            font-size: 48px ;
            position: relative ;
            color: #fff ;
            overflow: hidden ;
            text-shadow: 0 0 6px #fff ;
        }

        #loader-head p::before {
            content: 'Loading...' ;
            position: absolute ;
            top: 0 ;
            left: 0 ;
            width: 100% ;
            background: linear-gradient(45deg, #fff, #fff, #fff, #ff5, #f55, #55f) ;
            background-size: 200% ;
            background-clip: text ;
            -webkit-background-clip: text ;
            color: transparent ;
            animation: loaderTextAnim 1s ease infinite 0.75s ;
        }

        @keyframes loaderChase {
            0% { top: 0 ; left: 0 }
            12.5%, 25% { top: 0 ; left: 50% }
            37.5%, 50% { top: 50% ; left: 50% }
            62.5%, 75% { top: 50% ; left: 0 }
            87.5%, 100% { top: 0 ; left: 0 }
        }

        @keyframes loaderTextAnim {
            0% { background-position: 200% }
            90%, 100% { background-position: 0% }
        }
    </style>
</head>

<body>
    <div id="loader-head">
        <div id="loader">
            <div class="loaders" style="animation-delay: 200ms"></div>
            <div class="loaders" style="animation-delay: 900ms"></div>
            <div class="loaders" style="animation-delay: 1600ms"></div>
        </div>
        <p>Loading...</p>
    </div>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">

    Hello!

    <script>
        window.onload = function() {
            document.getElementById('loader-head').remove()
        }
    </script>
</body>

所以如果我把<link>里面<body>,动画加载器会在加载 CSS 文件时显示。但是根据一些人的说法,把它<link>放在里面是一个糟糕的想法和不好的做法。<body>

在这个测试中,我正在加载文件而没有实际对它们做任何事情。但在我的原始代码中,每个 CSS 文件都是必需的。

如何在加载 CSS 文件而不移动<link>标签内的<body>标签的情况下同时加载加载器?

标签: javascripthtmlcss

解决方案


我的简单解决方案是将 CSS 文件 URL 附加到 JS 并让它附加到document.head. 这里有点冗长,但它可以完美运行,而且很可能不会违反任何 HTML5 标准:


<head>
    <style>
    html, body { margin: 0 ; padding: 0 }

    #loader-head {
        height: 100vh ;
        width: 100% ;
        display: flex ;
        justify-content: center ;
        align-items: center ;
        flex-direction: column ;
        z-index: 10000 ;
        position: fixed ;
        top: 0 ;
        left: 0 ;
        background-color: #25DD84 ;
    }

    #loader-head > #loader { width: 150px ; height: 150px ; position: relative }

    #loader-head > #loader > .loaders {
        position: absolute ;
        width: 50px ;
        height: 50px ;
        background-color: #fff ;
        border-radius: 4px ;
        box-shadow: 0 0 6px #fff ;
        animation: loaderChase 2s ease infinite ;
    }

    #loader-head p {
        font-size: 48px ;
        position: relative ;
        color: #fff ;
        overflow: hidden ;
        text-shadow: 0 0 6px #fff ;
    }

    #loader-head p::before {
        content: 'Loading...' ;
        position: absolute ;
        top: 0 ;
        left: 0 ;
        width: 100% ;
        background: linear-gradient(45deg, #fff, #fff, #fff, #ff5, #f55, #55f) ;
        background-size: 200% ;
        background-clip: text ;
        -webkit-background-clip: text ;
        color: transparent ;
        animation: loaderTextAnim 1s ease infinite 0.75s ;
    }

    @keyframes loaderChase {
        0% { top: 0 ; left: 0 }
        12.5%, 25% { top: 0 ; left: 50% }
        37.5%, 50% { top: 50% ; left: 50% }
        62.5%, 75% { top: 50% ; left: 0 }
        87.5%, 100% { top: 0 ; left: 0 }
    }

    @keyframes loaderTextAnim {
        0% { background-position: 200% }
        90%, 100% { background-position: 0% }
    }
    </style>

    <link rel="preload" as="style" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <link rel="preload" as="style" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <link rel="preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">
    <link rel="preload" as="style" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">

    <script>
        const cssFiles = `
        stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min
        stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min
        cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min
        cdn.jsdelivr.net/npm/water.css@2/out/water
        `.split("\n")

        for(let cssFile of cssFiles) {
            cssFile = cssFile.trim()

            if(cssFile) {
                let link = document.createElement('link')
                link.rel = 'stylesheet'
                link.type = 'text/css'
                link.href = `https://${cssFile}.css`
                document.head.appendChild(link)
            }
        }

        window.onload = function() {
            document.getElementById('loader-head').remove()
        }
    </script>
</head>

<body>
    <div id="loader-head">
        <div id="loader">
            <div class="loaders" style="animation-delay: 200ms"></div>
            <div class="loaders" style="animation-delay: 900ms"></div>
            <div class="loaders" style="animation-delay: 1600ms"></div>
        </div>
        <p>Loading...</p>
    </div>

    Hello!
</body>

这是一个很长的动画:

在此处输入图像描述


推荐阅读