为什么会随机出现错误 Uncaught DOMException: Failed to execute 'querySelector' on 'Element': '' is not a valid selector
Why is there an error that occurs randomly saying Uncaught DOMException: Failed to execute 'querySelector' on 'Element': '' is not a valid selector
我创建了一个费用跟踪器应用程序,我将用户的费用记录按日期、标题、金额存储在 table 中,并为 'x' 按钮删除该行的空列费用文件。当用户单击 'x' 按钮时,它会从 firestore 中删除文档并从行中删除其数据。
偶尔,当点击 'x' 按钮时,文档会从 firestore 中删除,但不会从 table 中删除自身,除非页面被刷新,这基本上是重新读取费用文档因为文档已从 firestore 中删除。
app.js:189 Uncaught DOMException: Failed to execute 'querySelector' on 'Element': '[data-id=6yl9aPRGzLn1FCbXecfI]' is not a valid selector.
/* CURRENT MONTH'S EXPENSE TABLE */
const table = document.querySelector('#record');
function expenseRecord(user) {
const docRef = db.collection('users').doc(user.uid).collection(`${year}-${month}`).orderBy('date', 'desc').limit(20);
docRef.onSnapshot((snapshot) => {
let changes = snapshot.docChanges();
changes.forEach((change) => {
if (change.type == 'added') {
let tr = document.createElement('tr');
let date = document.createElement('td');
let title = document.createElement('td');
let amount = document.createElement('td');
let cross = document.createElement('td');
tr.setAttribute('data-id', change.doc.id);
cross.setAttribute('class', 'btnDelete');
date.textContent = change.doc.data().date;
title.textContent = change.doc.data().title;
amount.textContent = `$${change.doc.data().amount}`;
cross.textContent = 'x';
tr.appendChild(date);
tr.appendChild(title);
tr.appendChild(amount);
tr.appendChild(cross);
table.appendChild(tr);
cross.addEventListener('click', (e) => {
e.stopPropagation();
let id = e.target.parentElement.getAttribute('data-id');
db.collection('users').doc(user.uid).collection(`${year}-${month}`).doc(id).delete();
});
} else if (change.type == 'removed') {
let li = table.querySelector('[data-id=' + change.doc.id + ']');
table.removeChild(li);
}
});
});
}
<table id="record">
<tr>
<th>Date</th>
<th>Title</th>
<th>Amount</th>
<th></th>
</tr>
</table>
这是第 189 行
let li = table.querySelector('[data-id=' + change.doc.id + ']');
默认情况下,Firestore 生成的文档 ID 可以包含字母和数字。当 ID 以数字开头时,这会导致属性选择器失败,因为属性值周围没有引号,属性值将被视为 CSS <ident>
标记,不能以数字开头。这就是为什么您只会偶尔看到选择器失败的原因。
在属性值周围添加引号将确保它不会被解析器根据文档 ID 的性质区别对待:
let li = table.querySelector('[data-id="' + change.doc.id + '"]');
我创建了一个费用跟踪器应用程序,我将用户的费用记录按日期、标题、金额存储在 table 中,并为 'x' 按钮删除该行的空列费用文件。当用户单击 'x' 按钮时,它会从 firestore 中删除文档并从行中删除其数据。
偶尔,当点击 'x' 按钮时,文档会从 firestore 中删除,但不会从 table 中删除自身,除非页面被刷新,这基本上是重新读取费用文档因为文档已从 firestore 中删除。
app.js:189 Uncaught DOMException: Failed to execute 'querySelector' on 'Element': '[data-id=6yl9aPRGzLn1FCbXecfI]' is not a valid selector.
/* CURRENT MONTH'S EXPENSE TABLE */
const table = document.querySelector('#record');
function expenseRecord(user) {
const docRef = db.collection('users').doc(user.uid).collection(`${year}-${month}`).orderBy('date', 'desc').limit(20);
docRef.onSnapshot((snapshot) => {
let changes = snapshot.docChanges();
changes.forEach((change) => {
if (change.type == 'added') {
let tr = document.createElement('tr');
let date = document.createElement('td');
let title = document.createElement('td');
let amount = document.createElement('td');
let cross = document.createElement('td');
tr.setAttribute('data-id', change.doc.id);
cross.setAttribute('class', 'btnDelete');
date.textContent = change.doc.data().date;
title.textContent = change.doc.data().title;
amount.textContent = `$${change.doc.data().amount}`;
cross.textContent = 'x';
tr.appendChild(date);
tr.appendChild(title);
tr.appendChild(amount);
tr.appendChild(cross);
table.appendChild(tr);
cross.addEventListener('click', (e) => {
e.stopPropagation();
let id = e.target.parentElement.getAttribute('data-id');
db.collection('users').doc(user.uid).collection(`${year}-${month}`).doc(id).delete();
});
} else if (change.type == 'removed') {
let li = table.querySelector('[data-id=' + change.doc.id + ']');
table.removeChild(li);
}
});
});
}
<table id="record">
<tr>
<th>Date</th>
<th>Title</th>
<th>Amount</th>
<th></th>
</tr>
</table>
这是第 189 行
let li = table.querySelector('[data-id=' + change.doc.id + ']');
默认情况下,Firestore 生成的文档 ID 可以包含字母和数字。当 ID 以数字开头时,这会导致属性选择器失败,因为属性值周围没有引号,属性值将被视为 CSS <ident>
标记,不能以数字开头。这就是为什么您只会偶尔看到选择器失败的原因。
在属性值周围添加引号将确保它不会被解析器根据文档 ID 的性质区别对待:
let li = table.querySelector('[data-id="' + change.doc.id + '"]');