JavaScript如何实现点击音效仅在当前脚本所在页面播放?
问题原因
Cargo Collective 是单页应用(SPA)架构,站内跳转不会触发整页刷新,你通过addEventListener绑定在window上的点击事件不会随着页面切换自动销毁,所以哪怕跳转到没有嵌入这段脚本的页面,之前注册的监听函数依然在执行,点击就会播放音效。这个问题和浏览器缓存、window对象本身的特性无关,核心是事件监听器没有在离开页面时被清理。
你原来的写法还有个隐藏问题:如果用户反复进出嵌入脚本的页面,会重复给window绑定多个相同的监听事件,后续会出现点击一次、音效叠加播放多次的bug。
解决方法
方案1:单页面独立音效(仅在嵌入脚本的页面生效)
把你原来的代码替换成下面的写法,记得把TARGET_PATH的值改成你嵌入这段脚本的页面的路径(比如首页是/,作品页是/works/project-1):
// 替换成当前页面的路径 const TARGET_PATH = '/your-page-path'; function MouseSound() { // 兜底校验:当前路径不匹配直接终止播放 if (window.location.pathname !== TARGET_PATH) return; const audio = new Audio("https://files.cargocollective.com/c1242413/sound-1.mp3"); // 加catch捕获浏览器自动播放策略的静默报错,不影响功能 audio.play().catch(() => {}); } // 绑定点击监听 window.addEventListener('click', MouseSound, false); // 监听Cargo官方提供的页面离开事件,跳转时直接移除监听器,彻底避免跨页触发 window.addEventListener('cargo:page:leave', () => { window.removeEventListener('click', MouseSound, false); }); // 兼容用户直接关闭/刷新页面的场景 window.addEventListener('beforeunload', () => { window.removeEventListener('click', MouseSound, false); });
这段代码只会在你嵌入脚本的页面生效,跳转页面时会自动把绑定的点击事件删掉,不会残留到其他页面。
方案2:全局统一配置不同页面的不同音效
如果你需要多个页面各自对应不同点击音效,不用每个页面单独嵌脚本,直接把下面的代码放到全站全局脚本位置,自己在soundMap里配置路径和对应的音频地址即可:
// 配置路径和对应音效的映射关系 const soundMap = { '/': 'https://files.cargocollective.com/c1242413/sound-1.mp3', '/about': 'https://files.cargocollective.com/c1242413/sound-2.mp3', '/works': 'https://files.cargocollective.com/c1242413/sound-3.mp3' }; function playRouteSound() { const currentPath = window.location.pathname; // 当前页面没有配置音效就直接返回 if (!soundMap[currentPath]) return; const audio = new Audio(soundMap[currentPath]); audio.play().catch(() => {}); } // 全局只绑定一次监听,不用重复绑定 window.addEventListener('click', playRouteSound, false);
注意:浏览器默认会拦截无用户交互触发的自动播放,你这个逻辑是用户点击后才触发音频,完全符合浏览器规则,不会出现被拦截无法播放的问题。
内容的提问来源于stack exchange,提问作者Vanya K.
相关产品推荐
相关产品推荐

