[英]jQuery AJAX calls getting fired multiple times within click handler
I'm currently developing a PHP web app, and I'm making use of the datatables jQuery plugin, and jQuery AJAX calls to create a dynamic table that can have elements edited, deleted and added. 這(似乎)工作正常,但是,我觀察到在我的一些點擊處理程序中,AJAX 調用被多次觸發 - 我不太確定為什么。
這是目前的頁面,所以你知道我來自哪里:
如您所見,我有關於用戶的基本數據,以及左側的操作。 表中的每一行在 HTML 中如下所示:
<tr>
<td><?= $userAccount['firstName'] ?></td>
<td><?= $userAccount['lastName'] ?></td>
<td><?= $userAccount['email'] ?></td>
<td><?= $userAccount['jobTitle'] ?></td>
<td class="text-right enrolr-datatable-actions-min-width">
<i data-userId="<?= $userAccount['id'] ?>" class="fas fa-user-edit enrolr-standard-icon mr-2 event-user-edit"></i>
<i data-userId="<?= $userAccount['id'] ?>" class="fas fa-user-times enrolr-danger-icon mr-2 event-user-delete-staff"></i>
</td>
</tr>
由於(在初始頁面加載/渲染之后)這些表行被動態刪除/添加,因此我決定在文檔級別監聽事件以單擊.event-user-delete-staff
class,如下所示:
$(document).on('click', '.event-user-delete-staff', function () {
// Storing some details for later use by handlers
const userEmail = $(this).closest('tr').find('td').eq(2).html();
const $button = $(this);
// Shows confirm dialog, only performs deletion when "yes" is clicked, which causes the third function parameter to run
confirmDialog(`Are you sure you want to delete ${userEmail}? This action cannot be undone.`, 'Confirm Deletion', function () {
const $parentToRemove = $button.closest('tr');
// Make post to remove user.
$.ajax({
type: 'POST',
url: '../php/account/_deleteUser.php',
data: {
id: $button.attr('data-userId')
},
dataType: 'json',
success: function (response) {
// Handle response.
if (response.success == true) {
displaySuccessToast(response.message);
// Fade out row then update datatable.
$parentToRemove.fadeOut(500, () => {
staffTable.row($parentToRemove).remove().draw();
});
} else {
displayErrorToastStandard(response.message);
}
},
error: function () {
// Show error on failure.
displayErrorToastStandard('Something went wrong while handling this request');
}
});
});
});
現在,我注意到 AJAX 調用被多次調用的原因是因為我注意到每個刪除事件都會顯示多個 toast 消息( displaySuccessToast
方法,所有這些都是克隆一個 toast 模板並顯示它)。 基本上會發生以下情況:
添加了一些控制台日志並單步執行代碼后,我可以看出這不是因為$(document).on('click', '.event-user-delete-staff', function ()
事件偵聽器正在觸發多個每次刪除它只會觸發一次,因為它應該。
我認為嫌疑人是confirmDialog()
方法,正如我通過一些控制台日志觀察到的那樣,它在這里多次觸發。
此方法如下所示:
window.confirmDialog = function (message, title, yesCallback) {
// Sets some details in the confirm dialog
$('#confirmMessage').html(message);
$('#confirmTitle').html(title);
// Shows the modal
$('#confirmModal').modal('show');
// On the "yes" button within the dialog being clicked, hides modal and calls the yesCallback function.
$('#confirmBtnYes').on('click', function () {
$('#confirmModal').modal('hide');
yesCallback();
});
// On "no" just hides the modal.
$('#confirmBtnNo').on('click', function () {
$('#confirmModal').modal('hide');
});
}
但是,我懷疑這並不是這種方法的錯。 但是我對 function 這樣的回調如何工作以及在其中使用父級 scope 的變量是否存在某種誤解?
正如我所說; 我不認為這是因為事件偵聽器本身會觸發多次,在第二次刪除(及以后......)時,事件仍然只記錄被調用一次,它在confirmDialog
function 回調方法中,它記錄了兩次.
有人可以告訴我我在這里做錯了什么,什么可能導致這種行為?
編輯- 對於后代,以及其他任何偶然發現這一點並想知道我改變了什么的人......
這種情況下的問題是,每次調用confirmDialog
方法時,都會向 yes 按鈕添加另一個偵聽器。 這意味着,當單擊該對話框中的“是”按鈕時,它將觸發最近的事件......以及之前附加的所有其他事件。 我只是將確認按鈕是對話框更改為如下所示:
$('#confirmBtnYes').off().on('click', function () {
$('#confirmModal').modal('hide');
yesCallback();
});
首先使用off()
可確保沒有其他事件偵聽器在該 yes 按鈕上徘徊。 可能不是最好或最干凈的解決方案,但嘿,它有效。
感謝尼克在下面的回答,他指出了我哪里出錯了
每次調用confirmDialog
時,您都會在確認對話框中的Yes
按鈕中添加一個新的事件處理程序:
$('#confirmBtnYes').on('click', function () {
$('#confirmModal').modal('hide');
yesCallback();
});
這意味着第一次單擊 yes 按鈕時, yesCallback
將被調用一次,第二次yesCallback
將被調用兩次,依此類推。
您也對No
按鈕執行相同的操作,但由於這只是隱藏了模式,因此不會真正影響頁面的操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.