我正在尝试使用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
答案 0 :(得分:1)
希望我已经概述了我所做的所有更改:
js-
前缀来帮助维护代码时遵循HTML-> JS的逻辑,所以我建议这样做。document.querySelector('.delete')
仅会得到一个元素-您需要在querySelectorAll
,因为每个项目都有一个删除按钮。$('.carousel-item')
是(我假设)一个jQuery函数调用。这将获取文档中的所有.carousel-item
元素,而.attr('data-id')
将仅获取第一个元素的属性。如果要在此处使用jQuery,则需要从$(e.target).parent('.carousel-item')
之类的button元素上移DOM。但是,由于其他代码未使用jQuery,因此使用e.target.closest('.js-carousel-item')
,imo将更加一致。然后,要获得data-id
,我们可以轻松地使用element.dataset.id
。data
是否来自对db.collection('checkin').get()
的调用,但是如果它是代码中的Promise,而不是快照本身,则在遇到以下情况时会遇到问题您的删除按钮代码未嵌套在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>
答案 1 :(得分:0)
在字符串中使用onclick内联
例如
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="parentDiv"></div>
</body>
<script>
let element = `<div id="childDiv" onclick="myFunction()">click here</div>`;
document.getElementById("parentDiv").innerHTML = element;
function myFunction() {
console.log("works every time");
}
</script>
</html>
现在,子div插入了父div,并且具有onclick事件监听器
如果要循环播放,请不要在JS中循环播放addEventListener,也不要在模板文字中循环播放,换句话说,只需将其添加到字符串中即可,而不是额外的功能。
我刚刚对其进行了测试,并且..每次...时间
玩得开心!