【问题标题】:Javascript foreach loop calls ajax several timesJavascript foreach循环多次调用ajax
【发布时间】:2020-05-01 05:13:00
【问题描述】:

所以我正在尝试用几个板创建待办事项列表。每个板都有添加项目按钮。如果我单击添加项目按钮,它将打开插入任务信息的模式。但是,如果我多次单击添加项目按钮,然后将信息插入模式并按保存 ajax 触发多次我单击添加项目按钮。我该如何防止呢?

var addNewItems = document.querySelectorAll("#addNewItem");
var addNewSubmits = document.querySelectorAll("#listItemSave");
addNewItems.forEach(function(addNewItem) {
  addNewItem.addEventListener("click", function(e) {
    var newItemModal = this.nextElementSibling;
    newItemModal.classList.toggle("hidden");
    var addNewBtn = newItemModal.querySelector("#listItemSave");
    //current board
    var board = this.closest("div.list");
    //current list
    var list = board.querySelector(".todo--items");

    addNewBtn.addEventListener  ("click", function(e) {
      //current board id
      var boardId = board.dataset.boardid;
      //current title
      var title = newItemModal.querySelector("#listTitle");
      var titleValue = title.value;
      //current content
      var content = newItemModal.querySelector("#listTextarea");
      var contentValue = content.value;


      $.ajax({
        type: "POST",
        url: "add.php",
        data: { content: contentValue , title: titleValue , listid: boardId  },

        success: function(data, textStatus, jqXHR) {

        $("#todoItems-" + id + "").append(data);

       }
      });

    });
  });
});



【问题讨论】:

  • 你为什么在 ID 选择器上使用 querySelectorAll?
  • 每次执行附加到addNewItem 的事件处理程序时,它都会添加另一个事件处理程序到addNewBtn。因此,如果您单击三次addNewItem,然后单击一次addNewBtn,您将获得为第二次单击执行的三个处理程序。
  • 你怎么能拥有一件事的foreach? addnewitems 是 ID addNewItem。 ID是一个元素。 (至少应该是)
  • @VLAZ 那么如果我多次单击按钮,如何只制作一个事件处理程序?
  • @BryanDellinger 是的,我知道。现在它是 ID,因为我只有一个板,但现在我有几个板带有这个添加新模式,所以我将把那个 ID 更改为类。感谢您的通知。

标签: javascript jquery ajax foreach


【解决方案1】:

您可以使用变量,比如busy,来验证 AJAX 请求是否尚未进行。

您可以在 AJAx 的 beforeSend 回调中设置此变量,然后在 finally callbac 中将其更新为 false:

var addNewItems = document.querySelectorAll("#addNewItem");
var addNewSubmits = document.querySelectorAll("#listItemSave");
addNewItems.forEach(function (addNewItem) {
    addNewItem.addEventListener("click", function (e) {
        var newItemModal = this.nextElementSibling;
        newItemModal.classList.toggle("hidden");
        var addNewBtn = newItemModal.querySelector("#listItemSave");
        //current board
        var board = this.closest("div.list");
        //current list
        var list = board.querySelector(".todo--items");

        var busy = false;

        addNewBtn.addEventListener("click", function (e) {
            //current board id
            var boardId = board.dataset.boardid;
            //current title
            var title = newItemModal.querySelector("#listTitle");
            var titleValue = title.value;
            //current content
            var content = newItemModal.querySelector("#listTextarea");
            var contentValue = content.value;

            if (!busy) {
                $.ajax({
                    type: "POST",
                    url: "add.php",
                    beforeSend: () => {
                        busy = true;
                    }
                    data: {
                        content: contentValue,
                        title: titleValue,
                        listid: boardId
                    },
                    success: function (data, textStatus, jqXHR) {
                        $("#todoItems-" + id + "").append(data);
                    },
                    complete: () => {
                        busy = false;
                    }
                });
            }
        });
    });
});

这是一个非常简单的解决方案,但它确实有效。

【讨论】:

  • 由于某些原因,这个解决方案对我不起作用。
  • @MartynasTreigys 我没有对此进行测试,很有可能您不能简单地将其复制并粘贴到您的代码中。但是,您应该尝试了解我所做的并将其应用到您自己的上下文中。
【解决方案2】:

在这种情况下,您可以使用addNewBtn.onclick = function () {} 代替之前的监听器。 但不建议在另一个监听器中注册监听器。尝试将其移出那里。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多