我正在尝试使用 addEventListener 获取下面的按钮。它如何返回null。 html 是使用模板字符串从 js 呈现的。所以我想要实现的是 addEventListener 来删除模板字符串中的按钮。
// This is the template string
data.forEach(doc => {
checkin = doc.data();
card = `
<div class="carousel-item fieldId" data-id="${doc.id}">
<div class="col-12">
<div class="card checkCard" style="margin: 0 auto;">
<img src="${checkin.photo}" class="card-img-top" alt="...">
<button type="submit" class="btn center delete">
<i class="material-icons" style="font-size: 1em;">delete_forever</i>
</button>
<div class="card-body">
<h5 class="card-title">${checkin.title}</h5>
<p class="card-text">${checkin.description}</p>
</div>
</div>
</div>
</div>
`;
html += card;
});
checkinList.innerHTML = html;
//This is the delete button
const deleteContent = document.querySelector('.delete');
deleteContent.addEventListener('click', (e) => {
// get current document ID
console.log('hmm')
e.stopPropagation();
let id = $('.carousel-item').attr('data-id')
db.collection("checkin").doc(id).delete().then(() => {
console.log(id + "successfully deleted!");
$('.carousel-item').attr('data-id')
}).catch(function (error) {
console.error("Error removing document: ", error);
});
});
这是控制台的错误
Uncaught TypeError: Cannot read property 'addEventListener' of null
at index.js:123
(anonymous) @ index.js:123
最佳答案
希望我已经概述了我为使其正常工作所做的所有更改:
- 正如评论中所指出的,ID 必须是唯一的。类通常更适合用作 JavaScript(和 CSS) Hook 。许多人现在使用
js-
前缀来帮助维护代码时遵循 HTML -> JS 的逻辑,所以我建议这样做。 document.querySelector('.delete')
只会得到一个元素 - 您在这里需要querySelectorAll
,因为每个项目都有一个删除按钮。$('.carousel-item')
是(我假设)一个 jQuery 函数调用。这将获取文档中的所有.carousel-item
元素,而.attr('data-id')
将仅获取第一个元素的属性。如果你想在这里使用 jQuery,你会想要从按钮元素上升到 DOM,如$(e.target).parent('.carousel-item')
。但是,由于其他代码未使用 jQuery,因此使用e.target.closest('.js-carousel-item')
会更一致,imo。然后,要获取data-id
,我们可以很容易地使用element.dataset.id
。- > Don't use globals for this就像sao建议的那样
- 我不确定您示例中的
data
是否来自对db.collection('checkin').get()
的调用,但如果它是如果您的删除按钮代码未嵌套在then()
回调中,您将在您的代码中而不是快照本身遇到问题。 - 这更像是一个可选的旁注,但是通过将代码重构为使用
async
/await
,您的代码可以变得更具可读性。
我根据下面的示例包含了一个工作片段来演示:
;(() => {
// My attempt at a quick mock of Firebase to make this work as a snippet
const db = {
_collections: {
'checkin': [
{
id: 1,
photo: 'https://images.unsplash.com/photo-1508138221679-760a23a2285b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1267&q=80',
title: 'airplane w/ trees',
description: 'airplane on ground surrounded with trees',
}, {
id: 2,
photo: 'https://images.unsplash.com/photo-1485550409059-9afb054cada4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=701&q=80',
title: 'head to head',
description: 'minifigure head lot',
},
],
},
collection(key) {
const c = this._collections[key];
const doc = (id) => ({
id,
data() {
return c.find(o => o.id === id);
},
async delete() {
const idx = c.findIndex(o => o.id === id);
c.splice(idx, 1);
},
});
return {
doc,
async get() {
return c.map(o => o.id).map(doc);
},
};
},
}
const render = () => {
db.collection('checkin').get().then(snapshot => {
const cards = snapshot.map(doc => {
const checkin = doc.data();
return `
<div class="js-carousel-item carousel-item fieldId" data-id="${doc.id}">
<div class="col-12">
<div class="card checkCard" style="margin: 0 auto;">
<img src="${checkin.photo}" class="card-img-top" alt="...">
<button class="js-delete" type="submit" class="btn center">
<i class="material-icons" style="font-size: 1em;">delete_forever</i>
</button>
<div class="card-body">
<h5 class="card-title">${checkin.title}</h5>
<p class="card-text">${checkin.description}</p>
</div>
</div>
</div>
</div>`;
});
document.querySelector('.js-checkin-list').innerHTML = cards.join('');
// This is the delete button
const deleteButtons = document.querySelectorAll('.js-delete');
const deleteHandler = (e) => {
e.stopPropagation();
const el = e.target.closest('.js-carousel-item');
const id = +el.dataset.id;
db.collection('checkin').doc(id).delete().then(() => {
console.log(`${id} successfully deleted!`);
}).catch((error) => {
console.error('Error removing document: ', error);
})
render();
}
deleteButtons.forEach(
btn => btn.addEventListener('click', deleteHandler)
);
});
};
render();
})();
<div class="js-checkin-list carousel"></div>
关于javascript - 从模板字符串/文字中获取元素的 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57976075/