移动端Spotlight脚本异常:如何固定居中并保留PC端光标跟随?
问题修复:移动端Spotlight固定中心+PC端跟随光标
问题根源
- 移动端定位错误:原代码移动端使用
position: absolute,当页面内容超过视口高度时,height:100%仅覆盖初始视口,滚动后spotlight停留在顶部,无法跟随视口。 - 坐标计算问题:用
window.innerHeight/2px设置中心是绝对像素值,窗口缩放或页面滚动后会偏离视口中心。 - 语法错误:
spotlightSize变量末尾多余的括号,导致生成的backgroundImage格式错误,可能影响渲染。
修复方案
1. 调整CSS(核心:统一用fixed定位)
.spotlight { position: fixed; /* 固定在视口,不受页面滚动影响 */ width: 100vw; /* 覆盖整个视口宽度 */ height: 100vh; /* 覆盖整个视口高度 */ pointer-events: none; background-image: radial-gradient(circle at 50% 50%, transparent 160px, rgba(0, 0, 0, 0.85) 200px); top: 0; left: 0; /* 确保从视口左上角开始 */ } @media only screen and (min-width: 800px) { .spotlight { /* PC端仅调整背景透明度,保留fixed定位 */ background-image: radial-gradient(circle at 50% 50%, transparent 160px, rgba(0, 0, 0, 0) 200px); } }
2. 修正脚本(处理媒体查询变化+简化坐标)
window.addEventListener("DOMContentLoaded", ()=>{ const spotlight = document.querySelector('.spotlight'); const spotlightSize = 'transparent 160px, rgba(0, 0, 0, 0.85) 200px'; const mediaQuery = matchMedia('only screen and (min-width: 800px)'); // PC端光标跟随逻辑 function updateSpotlight(e) { const xPercent = (e.pageX / window.innerWidth) * 100; const yPercent = (e.pageY / window.innerHeight) * 100; spotlight.style.backgroundImage = `radial-gradient(circle at ${xPercent}% ${yPercent}%, ${spotlightSize})`; } // 处理设备切换(PC/移动端) function handleMediaChange(e) { if (e.matches) { window.addEventListener('mousemove', updateSpotlight); // PC端初始位置设为视口中心 spotlight.style.backgroundImage = `radial-gradient(circle at 50% 50%, ${spotlightSize})`; } else { window.removeEventListener('mousemove', updateSpotlight); // 移动端用百分比直接设为视口中心,无需计算像素 spotlight.style.backgroundImage = `radial-gradient(circle at 50% 50%, ${spotlightSize})`; } } // 初始化执行 handleMediaChange(mediaQuery); // 监听窗口尺寸变化,自动切换逻辑 mediaQuery.addEventListener('change', handleMediaChange); });
3. 简化HTML(移除冲突的内联样式)
<div class="spotlight"></div>
关键改进点
- 用
fixed定位替代移动端的absolute,确保spotlight始终覆盖视口,不受页面滚动影响。 - 移动端用
50% 50%百分比设置中心,避免像素计算带来的偏差,同时适配窗口缩放。 - 添加媒体查询变化监听,支持窗口尺寸切换时自动切换PC/移动端逻辑。
- 修复了
backgroundImage的语法错误。
内容的提问来源于stack exchange,提问作者Emanuele Pesa
相关产品推荐
相关产品推荐

