使用jQuery hashchange事件格式化URL哈希时如何避免无限循环
问题根因
现有代码的核心问题是last_hash赋值时机错误:你先把last_hash设为修改前的原始hash,再修改location.hash为带s-前缀的版本,这时候触发的hashchange事件里,新的带前缀hash和last_hash不一致,会再次进入判断逻辑。同时重复点击同一链接时,hash会在原始值和带前缀值之间来回切换,导致循环。
修复后代码
let last_hash = '' function manageHash() { const rawHash = window.location.hash // 已经是带s-前缀的hash,无需重复处理 if (rawHash.startsWith('#s-')) { last_hash = rawHash return } const targetId = 's-' + rawHash.substring(1) // 过滤空hash,同时校验对应锚点是否存在 if (targetId !== 's-' && document.getElementById(targetId)) { const processedHash = '#' + targetId // 先更新last_hash为最终值,避免修改hash后触发的hashchange重复执行逻辑 last_hash = processedHash window.location.hash = processedHash } } $(window).on('hashchange', function(e) { if (window.location.hash !== last_hash) { manageHash() } }); $(document).ready(function() { manageHash() })
逻辑说明
- 优先判断当前hash是否已经带
s-前缀,已带前缀的直接更新last_hash后跳过处理,不会重复修改 - 修改hash前先把
last_hash更新为处理后的目标值,修改hash触发的hashchange事件触发时,判断当前hash和last_hash相等,直接终止逻辑,彻底避免循环 - 即使用户重复点击同一个不带前缀的链接,每次hash变回不带前缀的状态,都会触发处理逻辑重新跳转到带前缀的锚点,不会出现点击无响应的问题
内容的提问来源于stack exchange,提问作者Lewis
相关产品推荐
相关产品推荐

