[英]addEventListener on dynamically created elements doesn't work
const monthAndYear = document.querySelector(".monthAndYear"); const habitContent = document.querySelector(".js-habit-content"); const trackerBody = document.querySelector(".js-tracker-body"); let today = new Date(); let currentMonth = today.getMonth(); let currentYear = today.getFullYear(); const months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ]; function showTracker(month, year) { const selectedDate = new Date(year, month); const lastDate = new Date( selectedDate.getFullYear(), selectedDate.getMonth() + 1, 0 ); let date = 1; for (let i = 0; i < 6; i++) { const row = document.createElement("tr"); for (let j = 0; j < 6; j++) { if (date <= lastDate.getDate()) { const cell = document.createElement("td"); const cellPtag = document.createElement("p"); const cellText = document.createTextNode(date); const cellIcon = document.createElement("i"); cell.setAttribute("class", "habit-count"); cellIcon.setAttribute("class", "fas fa-star star-icon"); cellPtag.appendChild(cellText); cell.appendChild(cellPtag); cell.appendChild(cellIcon); row.appendChild(cell); date++; } else { break; } } trackerBody.appendChild(row); } } showTracker(currentMonth, currentYear); document.body.addEventListener("click", function (e) { if (e.target && e.target.matches(".fa-star")) { e.target.classList.toggle("selected"); } });
.tracker-items { font-size: 20px; text-align: center; } tr { display: flex; }.habit-count { padding: 0 10px 15px 0; display: flex; flex-direction: column; justify-content: center; align-items: center; }.habit-count:last-child { padding-right: 0; }.habit-count p { margin-bottom: 5px; font-size: 14px; }.star-icon { font-size: 30px; color: #c2b7b0; }.selected { color: #f4df21; }
<div class="tracker-main"> <table class="traker-items"> <thead></thead> <tbody class="js-tracker-body"></tbody> </table> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.1/js/all.min.js" integrity="sha256-HkXXtFRaflZ7gjmpjGQBENGnq8NIno4SDNq/3DbkMgo=" crossorigin="anonymous"></script>
我正在嘗試構建一個習慣跟蹤器,並希望在單擊時更改 fontawesome 圖標的顏色。 但不知何故,它不能很好地工作。
function showTracker(month, year) {
const selectedDate = new Date(year, month);
const lastDate = new Date(
selectedDate.getFullYear(),
selectedDate.getMonth() + 1,
0
);
monthAndYear.innerHTML = `${months[month]} ${year}`;
trackerBody.innerHTML = "";
let date = 1;
for (let i = 0; i < 6; i++) {
const row = document.createElement("tr");
for (let j = 0; j < 6; j++) {
if (date <= lastDate.getDate()) {
const cell = document.createElement("td");
const cellPtag = document.createElement("p");
const cellText = document.createTextNode(date);
const cellIcon = document.createElement("i");
cell.setAttribute("class", "habit-count");
cellIcon.setAttribute("class", "fas fa-star star-icon");
cellPtag.appendChild(cellText);
cell.appendChild(cellPtag);
cell.appendChild(cellIcon);
row.appendChild(cell);
date++;
} else {
break;
}
}
trackerBody.appendChild(row);
}
}
showTracker(currentMonth, currentYear);
document.body.addEventListener("click", function (e) {
if (e.target && e.target.matches(".fa-star")) {
e.target.classList.toggle("selected");
}
});
我了解您不能直接在動態創建的元素上使用 querySelectorAll 然后 addEventListener 。 如果我單擊幾次,它會隨機工作,但仍然切換根本不起作用。 任何幫助將不勝感激!
查看生成的 DOM,並在if
語句之前添加一個console.log(e.target)
。
在創建<i>
元素時,font-awesome 將其替換為包含<path>
的<svg>
元素。
<svg>
元素是 class 的成員,但<path>
元素不是。
因此,只有在星號覆蓋的區域之外單擊 SVG 圖像時,切換才有效。
您可以更改邏輯,以便測試單擊的元素是 SVG 本身還是在其中繪制星形的<path>
。
if (e.target && e.target.matches(".fa-star") || e.target && e.target.parentNode.matches(".fa-star")) {
…或者在 DOM 中搜索任何匹配它的祖先(這將適用於更復雜的 SVG)。
if (e.target.closest(".fa-star"))
Closest 將匹配元素本身(它不僅僅針對祖先)。 您可以省略測試以查看e.target
是否存在,因為它總是會出現在點擊事件中。
您可以做的是在創建元素時附加事件偵聽器來執行該元素:
function showTracker(month, year) {
const selectedDate = new Date(year, month);
const lastDate = new Date(
selectedDate.getFullYear(),
selectedDate.getMonth() + 1,
0
);
monthAndYear.innerHTML = `${months[month]} ${year}`;
trackerBody.innerHTML = "";
let date = 1;
for (let i = 0; i < 6; i++) {
const row = document.createElement("tr");
for (let j = 0; j < 6; j++) {
if (date <= lastDate.getDate()) {
const cell = document.createElement("td");
const cellPtag = document.createElement("p");
const cellText = document.createTextNode(date);
const cellIcon = document.createElement("i");
cell.setAttribute("class", "habit-count");
cellIcon.setAttribute("class", "fas fa-star star-icon");
cellIcon.addEventListener("click", function (e) {
e.target.classList.toggle("selected");
});
cellPtag.appendChild(cellText);
cell.appendChild(cellPtag);
cell.appendChild(cellIcon);
row.appendChild(cell);
date++;
} else {
break;
}
}
trackerBody.appendChild(row);
}
}
showTracker(currentMonth, currentYear);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.