簡體   English   中英

動態創建的元素上的 addEventListener 不起作用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM