纯CSS实现的类似NextJS/LoadingJS的数据交付前的过渡动画

得益于loading.js,Nextjs的页面加载时候会出现非常友好的加载过渡动画。

如果我们想要在SSG/SSR渲染的HTML页中实现这一功能也很简单,只需要在ajax请求的数据交付之前写一个带有CSS动画过渡特效的容器在页面中预先占用即可,需要注意的是我们需要计算出容器的大小,这样就可以很自然的过渡到数据填入。

全部源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Skeleton Loading Example</title>
    <style>
        /* 骨架屏的基本样式 */
        .skeleton {
            background-color: #e0e0e0;
            border-radius: 4px;
            margin-bottom: 10px;
            position: relative;
            overflow: hidden;
        }
        .skeleton::after {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            height: 100%;
            width: 100%;
            background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 100%);
            animation: loading 1.5s infinite;
        }

        /* 动画效果 */
        @keyframes loading {
            0% {
                left: -100%;
            }
            100% {
                left: 100%;
            }
        }

        /* 实际数据加载后显示的样式 */
        .content {
            display: none;
        }
    </style>
</head>
<body>

    <div id="data-container">
        <!-- 骨架屏占位符 -->
        <div class="skeleton" style="width: 200px; height: 20px;"></div>
        <div class="skeleton" style="width: 300px; height: 20px;"></div>
        <div class="skeleton" style="width: 250px; height: 20px;"></div>
    </div>

    <script>
        // 使用AJAX调用示例
        function fetchData() {
            const xhr = new XMLHttpRequest();
            xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);
            xhr.onload = function () {
                if (this.status === 200) {
                    // 模拟数据请求成功后
                    const response = JSON.parse(this.responseText);

                    // 填充数据
                    document.getElementById('data-container').innerHTML = `
                        <div class="content">
                            <h3>${response.title}</h3>
                            <p>${response.body}</p>
                        </div>
                    `;

                    // 显示实际内容
                    const content = document.querySelector('.content');
                    content.style.display = 'block';
                }
            };

            // 模拟网络延迟,2秒后请求返回
            setTimeout(() => {
                xhr.send();
            }, 2000);
        }

        // 页面加载后立即执行AJAX请求
        window.onload = function() {
            fetchData();
        };
    </script>

</body>
</html>

Post Comment