网站跨页面加载动画重复执行问题:需实现仅首次加载并保持状态
问题:页面切换时重复触发加载动画
我在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(); } });
额外说明
- 如果需要用户关闭浏览器后重新触发加载,可以把
localStorage换成sessionStorage,后者会在浏览器关闭后自动清空数据 - 原代码的
setInterval未设置时间间隔,计数会瞬间完成,这里添加了20ms的间隔保证动画可见 - 恢复了你注释掉的动画逻辑,确保两种场景下都能正确应用样式
内容的提问来源于stack exchange,提问作者Mewt Mewt
相关产品推荐
相关产品推荐

