防止在 Bootstrap 模式中处理多个事件

Prevent multiple event handling in Bootstrap modal

提问人:genickstarre 提问时间:10/13/2023 更新时间:10/13/2023 访问量:40

问:

我有一个用于多个操作的引导模式,例如“添加用户”或“编辑用户”。每次我点击一个按钮,它都会为我打开模式,我可以填写字段并提交。 但是,如果我单击第一个按钮,然后单击第二个按钮,然后再次单击第一个按钮,它会连续向我发送 3 次帖子。因此,它每次都会为我创建一个新的事件侦听器。

如果我在 resetModal() 函数中删除事件侦听器,那么它每次只向我发送一次 POST,但随后按钮在第二次单击时不会出现,并且 console.log(state, 'state') 保持为空。如果我给 AddEventListener “once: true”,则行为完全相同。 所以我只能有一种行为。要么按钮在每次点击时都起作用,并且传递了数据状态等,要么每次提交只向我发送一个 POST。 我怎样才能做到这两件事都起作用?

我有一个非常简化的JSFiddle可以尝试使用:https://jsfiddle.net/dvkyjtbz/1/

const exampleModal = document.querySelector('#exampleModal');
let isEventListenerAttached = false;

function resetModal(event) {
  const modalForm = event.currentTarget.querySelector('form');

  if (modalForm) {
    modalForm.reset();
  }
  
  // Remove to run RemoveEventListener
  // exampleModal.removeEventListener('show.bs.modal', handleUserModal);
}

function saveUserData(user, state) {
  const {
    title,
    body,
    userId,
  } = user;
  const url = (userId) ? `/${userId}` : '';
  const modal = bootstrap.Modal.getInstance(exampleModal);

  axios({
      method: (userId) ? 'put' : 'post',
      url: `https://jsonplaceholder.typicode.com/posts${url}`,
      data: {
        title: title,
        body: body,
        userId: userId,
      },
    })
    .then(response => {
      console.log('Success!')
      modal.hide();
    })
    .catch((err) => {
      console.log(err);
    });
}

function handleSubmit(event, modal, state, userID) {
  event.preventDefault();

  const modalTitle = modal.querySelector('.modal-body #title');
  const modalBody = modal.querySelector('.modal-body #body');

  saveUserData({
    title: modalTitle.value,
    body: modalBody.value,
    userId: (state === 'newUser') ? '' : userID,
  }, state);
}

function handleUserModal(event) {
  if (isEventListenerAttached) {
    return;
  }

  const button = event.relatedTarget;
  const state = button.getAttribute('data-state') || 'newUser';
  const userID = button.getAttribute('data-uid');
  const modal = event.currentTarget;
  const saveUserButton = modal.querySelector('[form-submit="useradministration-save-user"]');
  const title = (state === 'newUser') ? 'Add New User' : 'Edit User';
  const modalTitle = modal.querySelector('.modal-title');
  
  if (modalTitle) {
    modalTitle.textContent = title;
  }
  
  console.log(state, 'state')

  saveUserButton.addEventListener('click', (event) => {
    handleSubmit(event, modal, state, userID);
  });
}

exampleModal.addEventListener('show.bs.modal', handleUserModal);
exampleModal.addEventListener('hidden.bs.modal', resetModal);
javascript 事件处理 模态对话框 bootstrap-modal

评论


答:

0赞 Ale_Bianco 10/13/2023 #1

您面临的问题与打开和关闭模式时多次添加事件侦听器有关。您可以跟踪是否已添加事件侦听器。

const exampleModal = document.querySelector('#exampleModal');
let isEventListenerAttached = false;

function resetModal(event) {
  const modalForm = event.currentTarget.querySelector('form');

  if (modalForm) {
    modalForm.reset();
  }
}

function saveUserData(user, state) {
  // ...
}

function handleSubmit(event, modal, state, userID) {
  event.preventDefault();

  const modalTitle = modal.querySelector('.modal-body #title');
  const modalBody = modal.querySelector('.modal-body #body');

  saveUserData({
    title: modalTitle.value,
    body: modalBody.value,
    userId: (state === 'newUser') ? '' : userID,
  }, state);
}

function handleUserModal(event) {
  if (isEventListenerAttached) {
    return;
  }

  const button = event.relatedTarget;
  const state = button.getAttribute('data-state') || 'newUser';
  const userID = button.getAttribute('data-uid');
  const modal = event.currentTarget;
  const saveUserButton = modal.querySelector('[form-submit="useradministration-save-user"]');
  const title = (state === 'newUser') ? 'Add New User' : 'Edit User';
  const modalTitle = modal.querySelector('.modal-title');

  if (modalTitle) {
    modalTitle.textContent = title;
  }

  saveUserButton.addEventListener('click', (event) => {
    handleSubmit(event, modal, state, userID);
  });

  isEventListenerAttached = true; // Set to true after adding the event listener
}

function removeEventListener() {
  const saveUserButton = exampleModal.querySelector('[form-submit="useradministration-save-user"]');
  saveUserButton.removeEventListener('click', (event) => {
    handleSubmit(event, exampleModal, 'newUser', null);
  });
}

exampleModal.addEventListener('show.bs.modal', handleUserModal);
exampleModal.addEventListener('hidden.bs.modal', resetModal);
exampleModal.addEventListener('hide.bs.modal', removeEventListener);

评论

0赞 genickstarre 10/13/2023
感谢您的快速回复,但这也不起作用。如果我首先单击第一个按钮“新用户”,然后单击“编辑用户”,则模式的标题仍为“添加新用户”。好像它然后缓存了任何东西。我在这里调整了JSFiddle:链接