Firestore .get()在JQuery .on点击事件中无法正常运行的问题
解决Firestore异步请求与页面跳转的冲突问题
这个问题本质是异步操作的时序和页面跳转的优先级冲突导致的:浏览器跳转页面会立刻终止当前页面的所有未完成任务,所以不阻止默认行为时,Firestore的异步请求还没拿到结果就被中断了;但阻止默认行为后,请求能完成,页面又没法正常跳转。给你两个实用的解决思路,按需选择:
方案一:先获取数据再手动跳转(借助localStorage传递数据)
先阻止默认跳转,等Firestore请求完成后把数据存在本地存储,再手动跳转到目标页面,最后在new.html里读取数据。
当前页面的点击事件代码:
// 选中所有符合条件的Bootstrap卡片 document.querySelectorAll('#city-card[data-id][href="new.html"]').forEach(card => { card.addEventListener('click', async (e) => { // 先阻止默认跳转行为 e.preventDefault(); // 获取卡片上的data-id值 const cityName = e.currentTarget.dataset.id; try { // 从Firestore获取对应城市的文档 const docRef = db.collection('cities').doc(cityName); const docSnap = await docRef.get(); if (docSnap.exists) { // 把数据转成JSON字符串存在localStorage localStorage.setItem('selectedCityData', JSON.stringify(docSnap.data())); // 手动跳转到目标页面 window.location.href = e.currentTarget.href; } else { console.log('⚠️ 未找到对应城市的文档'); } } catch (error) { console.error('❌ 获取Firestore文档失败:', error); } }); });
new.html页面的代码(读取数据):
// 页面加载完成后读取数据 window.addEventListener('DOMContentLoaded', () => { const cityData = JSON.parse(localStorage.getItem('selectedCityData')); if (cityData) { // 在这里用数据渲染页面即可 console.log('✅ 获取到的城市数据:', cityData); // 用完记得清除缓存,避免下次页面加载时残留旧数据 localStorage.removeItem('selectedCityData'); } });
方案二:通过URL参数传递ID,在new.html中请求数据(更推荐)
这种方式不需要依赖本地存储,直接把data-id作为URL参数传递给new.html,在目标页面发起Firestore请求。优点是逻辑更清晰,不会有缓存残留的问题。
当前页面的点击事件代码:
document.querySelectorAll('#city-card[data-id][href="new.html"]').forEach(card => { card.addEventListener('click', (e) => { e.preventDefault(); const cityName = e.currentTarget.dataset.id; // 把城市名称编码后拼到URL参数里 const targetUrl = `${e.currentTarget.href}?city=${encodeURIComponent(cityName)}`; // 手动跳转 window.location.href = targetUrl; }); });
new.html页面的代码(获取参数并请求数据):
window.addEventListener('DOMContentLoaded', async () => { // 解析URL参数 const urlParams = new URLSearchParams(window.location.search); const cityName = urlParams.get('city'); if (cityName) { try { // 解码后请求Firestore文档 const docRef = db.collection('cities').doc(decodeURIComponent(cityName)); const docSnap = await docRef.get(); if (docSnap.exists) { console.log('✅ 城市文档数据:', docSnap.data()); // 在这里渲染页面内容 } else { console.log('⚠️ 未找到该城市的文档'); } } catch (error) { console.error('❌ 获取文档失败:', error); } } else { console.log('⚠️ 未获取到城市名称参数'); } });
方案对比
- 如果数据量小且不需要持久化,方案二更简洁安全,推荐使用;
- 方案一适合需要传递大量数据的场景,但要注意localStorage的存储限制(约5MB),以及清理缓存的问题。
内容的提问来源于stack exchange,提问作者Ryland King
相关产品推荐
相关产品推荐

