You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

网站跨页面加载动画重复执行问题:需实现仅首次加载并保持状态

问题:页面切换时重复触发加载动画

我在index.html与about.html中都配置了div#load作为网站加载屏,通过JavaScript的counter函数实现从0%到100%的计数逻辑;当计数到达100%时,会为其他div元素添加classList以实现动画效果。

目前的问题是:切换至about.html或返回index.html时,加载计数都会从0%重新开始并执行至100%。需求是仅在首次访问时触发加载计数,切换页面时已添加的classList保持生效,不再重复触发加载动画。


现有代码

HTML代码

<div id="load">
    <div id="load-wrapper">
        <div id="load-no">0</div>
    </div>
</div>

JavaScript代码

function counter(){
    const counts = setInterval(function(){
        var load_no = document.getElementById('load-no'),
            number = parseInt(load_no.textContent);
        /* const load = document.getElementById('load');
        const ev_logo = document.getElementById('ev-logo');
        const nav_a_select = document.querySelectorAll('.nav-a');
        const fb_icon = document.querySelector('.fb-icon')
        const github_icon = document.querySelector('.github-icon')
        const line_h = document.querySelector('.line-h');
        const line_v = document.querySelector('.line-v');
        const copyright_icon = document.querySelector('.copyright-icon');
        const year = document.querySelector('.year');
        const name = document.querySelector('.name'); */
        load_no.textContent = (++number).toString();/* 
        const earl_villarias = document.querySelector('.earl-villarias')
        const slogan_text = document.querySelector('.slogan-text')
        const slogan_line_select = document.querySelectorAll('.slogan-line') */

        if (load_no.textContent==100){
            clearInterval(counts);
            /* load.style.pointerEvents = 'none';
            load_no.style.transform = 'translate3d(0px, -110%, 0px)';
            ev_logo.style.transform = 'translate3d(0px, 0px, 0px)';
            fb_icon.classList.add('fb-icon-s')
            github_icon.classList.add('github-icon-s')
            line_h.classList.add('line-expand-h')
            line_v.classList.add('line-expand-v')
            copyright_icon.classList.add('icon-year-s')
            year.classList.add('icon-year-s')
            name.classList.add('name-s')
            for (const nav_a of nav_a_select) {
                nav_a.classList.add('s-d')
            }
            earl_villarias.classList.add('name-show')
            slogan_text.classList.add('slogan-show')
            for (const slogan_line of slogan_line_select) {
                slogan_line.classList.add('slogan-line-expand')
            }
            load_no.textContent = number; */
        }
    })
}
counter();

解决方案:用localStorage标记加载状态

核心思路是利用浏览器的localStorage存储一个状态标记,记录用户是否已完成首次加载动画。每次页面加载时先检查该标记:

  • 若标记不存在或为false,执行加载计数逻辑,完成后设置标记为true
  • 若标记为true,直接隐藏加载屏并手动应用所有动画class,跳过计数过程

修改后的JavaScript代码

function counter(){
    // 给定时器加时间间隔,让计数过程可见
    const counts = setInterval(function(){
        const load_no = document.getElementById('load-no');
        let number = parseInt(load_no.textContent);
        
        load_no.textContent = (++number).toString();

        if (load_no.textContent == 100){
            clearInterval(counts);
            // 执行动画逻辑
            const load = document.getElementById('load');
            const ev_logo = document.getElementById('ev-logo');
            const nav_a_select = document.querySelectorAll('.nav-a');
            const fb_icon = document.querySelector('.fb-icon');
            const github_icon = document.querySelector('.github-icon');
            const line_h = document.querySelector('.line-h');
            const line_v = document.querySelector('.line-v');
            const copyright_icon = document.querySelector('.copyright-icon');
            const year = document.querySelector('.year');
            const name = document.querySelector('.name');
            const earl_villarias = document.querySelector('.earl-villarias');
            const slogan_text = document.querySelector('.slogan-text');
            const slogan_line_select = document.querySelectorAll('.slogan-line');

            load.style.pointerEvents = 'none';
            load_no.style.transform = 'translate3d(0px, -110%, 0px)';
            ev_logo.style.transform = 'translate3d(0px, 0px, 0px)';
            fb_icon.classList.add('fb-icon-s');
            github_icon.classList.add('github-icon-s');
            line_h.classList.add('line-expand-h');
            line_v.classList.add('line-expand-v');
            copyright_icon.classList.add('icon-year-s');
            year.classList.add('icon-year-s');
            name.classList.add('name-s');
            
            for (const nav_a of nav_a_select) {
                nav_a.classList.add('s-d');
            }
            earl_villarias.classList.add('name-show');
            slogan_text.classList.add('slogan-show');
            for (const slogan_line of slogan_line_select) {
                slogan_line.classList.add('slogan-line-expand');
            }
            
            // 标记已完成首次加载
            localStorage.setItem('hasLoaded', 'true');
        }
    }, 20);
}

// 页面DOM加载完成后检查状态
window.addEventListener('DOMContentLoaded', function() {
    const hasLoaded = localStorage.getItem('hasLoaded');
    const load = document.getElementById('load');
    const load_no = document.getElementById('load-no');
    
    if (hasLoaded === 'true') {
        // 直接隐藏加载屏并应用所有动画class
        load.style.display = 'none';
        const ev_logo = document.getElementById('ev-logo');
        const nav_a_select = document.querySelectorAll('.nav-a');
        const fb_icon = document.querySelector('.fb-icon');
        const github_icon = document.querySelector('.github-icon');
        const line_h = document.querySelector('.line-h');
        const line_v = document.querySelector('.line-v');
        const copyright_icon = document.querySelector('.copyright-icon');
        const year = document.querySelector('.year');
        const name = document.querySelector('.name');
        const earl_villarias = document.querySelector('.earl-villarias');
        const slogan_text = document.querySelector('.slogan-text');
        const slogan_line_select = document.querySelectorAll('.slogan-line');

        ev_logo.style.transform = 'translate3d(0px, 0px, 0px)';
        fb_icon.classList.add('fb-icon-s');
        github_icon.classList.add('github-icon-s');
        line_h.classList.add('line-expand-h');
        line_v.classList.add('line-expand-v');
        copyright_icon.classList.add('icon-year-s');
        year.classList.add('icon-year-s');
        name.classList.add('name-s');
        
        for (const nav_a of nav_a_select) {
            nav_a.classList.add('s-d');
        }
        earl_villarias.classList.add('name-show');
        slogan_text.classList.add('slogan-show');
        for (const slogan_line of slogan_line_select) {
            slogan_line.classList.add('slogan-line-expand');
        }
    } else {
        // 首次访问,执行加载计数
        counter();
    }
});

额外说明

  1. 如果需要用户关闭浏览器后重新触发加载,可以把localStorage换成sessionStorage,后者会在浏览器关闭后自动清空数据
  2. 原代码的setInterval未设置时间间隔,计数会瞬间完成,这里添加了20ms的间隔保证动画可见
  3. 恢复了你注释掉的动画逻辑,确保两种场景下都能正确应用样式

内容的提问来源于stack exchange,提问作者Mewt Mewt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 00:12:03