簡體   English   中英

點擊事件監聽器觸發多次

[英]Click event listener fires multiple times

我有一個嵌套的<i>標記,顯示喜歡或不喜歡的心。 問題是,每次喜歡一個帖子時,它都會發送大約 16 個請求(事件觸發 16 次)。 我試過使用sleepseTimeout無濟於事。 我需要將事件偵聽器動態添加到<i>標記。

initial_html

{% if user in post.get_likers%}
        <p class="my-0 text-muted"><i style="color: red;" class="fas fa-heart hover"></i> {{post.total_likes}}</p>
{% else %}
        <p class="my-0 text-muted"><i class="far fa-heart hover"></i> {{post.total_likes}}</p>
{% endif %}

嘗試更新每個視圖的喜歡

document.addEventListener("DOMContentLoaded", () => {
  load_clickable();
});

function load_clickable() {
  document.querySelectorAll("i").forEach((item) => {
    item.addEventListener("click", () => {
      update_likes(item);
    });
  });
}

function update_likes(item) {
  const p_tag = item.parentNode;
  const post_id = p_tag.parentNode.id;
  console.log(post_id, p_tag.innerText);
  const fetch_url = `/like/${post_id}`;
  fetch(fetch_url, {
    method: "POST",
  })
    .then((response) => response.json())
    .then((result) => {
      if (result.like) {
        console.log("Has Liked");
        var new_likes = parseInt(p_tag.innerText) + 1;
        p_tag.innerHTML = `<i style="color: red;" class="fas fa-heart hover"></i> ${new_likes}`;
      } else if (result.unlike) {
        console.log("Has unliked");
        var new_likes = parseInt(p_tag.innerText) - 1;
        p_tag.innerHTML = `<i class="far fa-heart hover"></i> ${new_likes}`;
      }
      load_clickable();
    });
}

我怎樣才能使每個事件觸發一次?

問題是您在更新喜歡后調用load_clickable ,這會再次將事件偵聽器添加到所有<i>元素。 相反,您應該在<span>中顯示喜歡的數量並每次更新textContent ,這樣您就不需要再次附加所有事件偵聽器。

更新了 HTML:

{% if user in post.get_likers%}
        <p class="my-0 text-muted"><i style="color: red;" class="fas fa-heart hover"></i> <span>{{post.total_likes}}</span></p>
{% else %}
        <p class="my-0 text-muted"><i class="far fa-heart hover"></i> <span>{{post.total_likes}}</span></p>
{% endif %}

更新了 JavaScript(為簡潔起見省略了部分):

//...
.then((result) => {
      if (result.like) {
        console.log("Has Liked");
        var new_likes = parseInt(p_tag.innerText) + 1;
        p_tag.querySelector('span').textContent = new_likes;
      } else if (result.unlike) {
        console.log("Has unliked");
        var new_likes = parseInt(p_tag.innerText) - 1;
        p_tag.querySelector('span').textContent = new_likes;
      }
    });
//...

調用 load_clickable 方法是問題所在,點擊事件在技術上仍然處於活動狀態,為什么不將onclick attr 加載到新的 i 標簽,就像這樣

.then((result) => {
      if (result.like) {
        console.log("Has Liked");
        var new_likes = parseInt(p_tag.innerText) + 1;
        p_tag.innerHTML = `<i style="color: red;" class="fas fa-heart hover" onclick=update_likes(this)></i> ${new_likes}`;
      } else if (result.unlike) {
        console.log("Has unliked");
        var new_likes = parseInt(p_tag.innerText) - 1;
        p_tag.innerHTML = `<i class="far fa-heart hover" onclick=update_likes(this)></i> ${new_likes}`;
      }
    });

最佳解決方案

{% if user in post.get_likers%}
        <p class="my-0 text-muted"><i style="color: red;" class="fas fa-heart hover onclick=update_likes()"></i> <span>{{post.total_likes}}</span></p>
{% else %}
        <p class="my-0 text-muted"><i class="far fa-heart hover onclick=update_likes()"></i> <span>{{post.total_likes}}</span></p>
{% endif %}

然后 javascript

document.addEventListener("DOMContentLoaded", () => {
    //do something else with loaded DOM
});

function update_likes() {
  const p_tag = this.parentNode;
  const post_id = p_tag.parentNode.id;
  console.log(post_id, p_tag.innerText);
  const fetch_url = `/like/${post_id}`;
  fetch(fetch_url, {
    method: "POST",
  })
    .then((response) => response.json())
    .then((result) => {
      if (result.like) {
        console.log("Has Liked");
        var new_likes = parseInt(p_tag.innerText) + 1;
        p_tag.innerHTML = `<i style="color: red;" class="fas fa-heart hover" onclick=update_likes(this)></i> ${new_likes}`;
      } else if (result.unlike) {
        console.log("Has unliked");
        var new_likes = parseInt(p_tag.innerText) - 1;
        p_tag.innerHTML = `<i class="far fa-heart hover" onclick=update_likes(this)></i> ${new_likes}`;
      }
    });
}

這樣所有標簽都已經用它們的標簽呈現

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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