如何从Firestore查询列表中获取点击文档的ID?
嘿,我来帮你搞定这个问题!你遇到的问题主要是引号嵌套冲突和变量未正确作为字符串传递导致的语法错误,我给你几个靠谱的解决方案,从简单到健壮的都有:
首先,说说你代码里的问题
你写的按钮onclick属性里用了单引号包裹函数内容,但函数里又用单引号去选cityDetail,这就导致浏览器解析时会提前闭合引号,直接报错。另外如果id是字符串类型,你直接写=+id会让浏览器把它当成变量,而不是字符串值。
方案1:用事件委托(最推荐,高效又健壮)
动态添加的元素(比如你循环生成的按钮)用事件委托是最好的选择,只需要给父容器加一次监听,就能处理所有子按钮的点击事件,还能避免闭包问题:
// 先查询Firestore并生成列表项 db.collection("cities").where("capital", "==", true) .get() .then(function(querySnapshot) { const citiesList = document.getElementById("cities-list"); querySnapshot.forEach(function(doc) { const docId = doc.id; const cityId = doc.data().id; // 用模板字符串写HTML,更清晰易读 const itemHtml = ` <div class="city-row"> Id: ${cityId}<br> <button class="city-select-btn" data-id="${docId}">Set clicked city</button> </div> `; citiesList.innerHTML += itemHtml; }); }); // 给父容器添加事件委托 document.getElementById("cities-list").addEventListener('click', function(e) { // 判断点击的是我们的按钮 if (e.target.classList.contains('city-select-btn')) { // 从按钮的data属性里取出文档ID const clickedDocId = e.target.dataset.id; // 更新目标div的内容 document.getElementById("result-list").innerHTML = clickedDocId; } });
这里我们把文档ID存在按钮的data-id属性里,点击时通过事件对象获取这个值,完全避开了引号嵌套的麻烦。
方案2:修复inline onclick的引号问题(不推荐,但适合快速调试)
如果你一定要用inline onclick,需要正确转义引号,并且把id用引号包裹成字符串:
templ = "Id: "+id+"<br>"+ "<button onclick='document.getElementById(\"cityDetail\").innerHTML=\""+ id +"\"'>Set clicked city</button><br>";
这里外层用双引号包裹HTML,内层onclick里用转义的双引号\"来包裹元素ID和字符串值,这样浏览器就能正确解析了。不过这种方式容易出问题(比如id里有特殊字符的话会报错),所以还是更推荐第一种方案。
方案3:用DOM方法创建元素(最安全,避免XSS风险)
如果你的数据里包含用户输入的内容,用HTML字符串拼接可能会有XSS风险,这时候直接用DOM API创建元素更安全:
db.collection("cities").where("capital", "==", true) .get() .then(function(querySnapshot) { const citiesList = document.getElementById("cities-list"); querySnapshot.forEach(function(doc) { const docId = doc.id; const cityId = doc.data().id; // 创建一行的容器 const rowDiv = document.createElement('div'); // 添加文本内容 rowDiv.innerHTML = `Id: ${cityId}<br>`; // 创建按钮 const selectBtn = document.createElement('button'); selectBtn.textContent = "Set clicked city"; // 直接给按钮加点击事件 selectBtn.addEventListener('click', function() { document.getElementById("result-list").innerHTML = docId; }); // 把按钮加到行里,再把行加到列表容器 rowDiv.appendChild(selectBtn); citiesList.appendChild(rowDiv); }); });
这种方式完全不用拼接HTML字符串,所有元素都是通过DOM API创建的,安全性拉满,也不会有引号问题。
总结
优先选事件委托或者DOM创建元素的方式,这两种都能避免你遇到的闭包/引号错误,而且代码更易维护、更安全。
内容的提问来源于stack exchange,提问作者cristtiano
相关产品推荐
相关产品推荐

