如何判断页面是首次加载还是通过Ctrl+F5强制刷新?
解决Material Icons加载前显示文本的问题
核心问题拆解
你遇到的是字体加载完成前,图标元素内的文本提前渲染的问题,同时需要区分首次/强制刷新来控制动画触发逻辑。下面是几个实用的解决方案:
1. 先解决文本闪现问题(无需判断刷新)
最直接的方式是通过CSS+JS监听字体加载状态,完全隐藏未就绪的图标,加载完成后再淡入,不管是哪种刷新都能避免文本显示:
CSS 代码
/* 初始状态:隐藏图标,透明 */ .material-icons { visibility: hidden; opacity: 0; transition: opacity 0.3s ease; } /* 字体加载完成后显示并淡入 */ .material-icons.loaded { visibility: visible; opacity: 1; }
JS 代码
// 监听字体加载完成事件(现代浏览器支持) document.fonts.ready.then(() => { document.querySelectorAll('.material-icons').forEach(icon => { icon.classList.add('loaded'); }); }); // 兼容旧浏览器:设置兜底延迟 if (!document.fonts) { setTimeout(() => { document.querySelectorAll('.material-icons').forEach(icon => { icon.classList.add('loaded'); }); }, 300); }
2. 区分首次加载与强制刷新
如果必须控制动画只在首次/强制刷新时触发,可以用sessionStorage结合时间戳判断:
JS 代码
const lastLoadTime = sessionStorage.getItem('lastPageLoadTime'); const currentTime = Date.now(); let isForceRefresh = false; // 时间差小于500ms判定为强制刷新(可根据实际调整) if (lastLoadTime) { isForceRefresh = (currentTime - parseInt(lastLoadTime)) < 500; } // 更新本次加载时间戳 sessionStorage.setItem('lastPageLoadTime', currentTime); // 根据状态添加对应类 document.fonts.ready.then(() => { document.querySelectorAll('.material-icons').forEach(icon => { if (isForceRefresh || !lastLoadTime) { // 首次加载或强制刷新:延迟淡入 icon.classList.add('delayed-fade-in'); } else { // 普通刷新:直接显示 icon.classList.add('loaded'); } }); });
对应CSS 扩展
/* 延迟淡入动画 */ .material-icons.delayed-fade-in { visibility: visible; animation: fadeIn 0.5s ease 0.2s forwards; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
3. 原生CSS替代方案(无需JS)
利用font-display: swap属性,让浏览器先使用占位样式,等字体加载完成后再替换,配合初始隐藏CSS即可:
修改Material Icons的字体声明,添加font-display: swap:
@font-face { font-family: 'Material Icons'; font-style: normal; font-weight: 400; src: url(你的字体文件路径) format('woff2'); font-display: swap; }
再配合之前的初始隐藏CSS,就能稳定解决文本闪现问题,无需额外JS逻辑。
内容的提问来源于stack exchange,提问作者Kemal Özvarol
相关产品推荐
相关产品推荐

