首页 > 解决方案 > 使用香草javascript关闭模态时从正文中删除类

问题描述

我的页面上有多个模式,当单击相应的按钮时会打开。当模式打开时,它将类添加.has-modal-open到正文以防止页面滚动。问题是当我关闭模式时,该类不会从正文标签中删除。我试过body.classList.remove('has-modal-open');了,但由于某种原因它不起作用。我正在寻找一个香草 javascript 解决方案。

谢谢你。

  const modal = document.querySelectorAll('.modal');
  const modalOpenButtons = document.querySelectorAll('[data-open-modal]');
  const modalCloseButtons = document.querySelectorAll('[data-close-modal]');
  const body = document.querySelector('body');
  
  for (let i = 0; i < modalOpenButtons.length; i++) {
    const modalOpenButton = modalOpenButtons[i];
    modalOpenButton.addEventListener('click', e => {
      body.classList.add('has-modal-open');
      const modalDataAttribute = e.target.getAttribute('data-open-modal');
      document.querySelector('.modal[data-open-modal=\''.concat(modalDataAttribute, '\']')).classList.add('modal--is-open');
    });
  }
  
  for (let i = 0; i < modalCloseButtons.length; i++) {
    body.classList.remove('has-modal-open');
    const modalCloseButton = modalCloseButtons[i];
    modalCloseButton.addEventListener('click', e => {
      e.target.closest('.modal').classList.remove('modal--is-open');
    });
  }
  
  for (let i = 0; i < modal.length; i++) {
    const modals = modal[i];
    document.addEventListener('keydown', e => {
      if (e.keyCode === 27) {
        modals.classList.remove('modal--is-open')
      }
    })
    modals.addEventListener('click', e => {
      e.target.classList.remove('modal--is-open')
    })
  }
.modal {
  display: none;
  justify-content: center;
  align-items: center;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  max-height: calc(100% - 48px);
  background: rgba(0, 0, 0, 0.45);
  z-index: 90;
}

.modal__header {
  position: relative;
  border-radius: 4px 4px 0 0;
  background-color: white;
  width: 100%;
  min-height: 60px;
  overflow: auto;
}

.modal__body {
  position: relative;
  width: calc(100% - 48px);
  max-width: 900px;
  max-height: calc(100% - 48px);
  overflow: hidden;
  border-radius: 4px;
  max-height: 700px;
  background: white;
}

.modal__content {
  padding: 0 40px 40px;
  overflow: auto;
  height: 100px;
}

.modal--is-open {
  display: flex;
}

.has-modal-open {
  overflow-y: hidden;
}


.modal__close {
  position: absolute;
  top: 32px;
  right: 12px;
  transform: translateY(-50%);
  width: 56px;
  height: 56px;
  padding: 0;
}
<button class="button" data-open-modal="open-modal-1">Open modal</button>

<div class="modal" data-open-modal="open-modal-1">
  <div class="modal__body">
    <div class="modal__header">
      <button class="modal__close" data-close-modal>X</button>
    </div>
    <div class="modal__content">
      My modal
    </div>
  </div>
</div>

标签: javascriptmodal-dialog

解决方案


您的代码有两个问题:

  • body.classList.remove('has-modal-open');应该在关闭按钮的 eventListener 内部调用,但您之前调用过它。
  • modalOpenButtons = document.querySelectorAll('[data-open-modal]');不仅选择按钮,还选择具有属性的模式data-open-modal。当您单击关闭按钮时,模式也会被单击,因此在您的情况下调用附加到modalOpenButtons. 您应该只将按钮放在 中modalOpenButtons,例如:

const modalOpenButtons = document.querySelectorAll('button[data-open-modal]');

我在下面制作了一个片段,您可以在其中看到该类已正确添加/删除

const modal = document.querySelectorAll('.modal');
  const modalOpenButtons = document.querySelectorAll('button[data-open-modal]');
  const modalCloseButtons = document.querySelectorAll('[data-close-modal]');
  const body = document.querySelector('body');
  
  for (let i = 0; i < modalOpenButtons.length; i++) {
    const modalOpenButton = modalOpenButtons[i];
    modalOpenButton.addEventListener('click', e => {
      body.classList.add('has-modal-open');
      const modalDataAttribute = e.target.getAttribute('data-open-modal');
      //document.querySelector(`.modal[data-open-modal="${modalDataAttribute}"]`).classList.add('modal--is-open');
      document.querySelector('.modal[data-open-modal=\''.concat(modalDataAttribute, '\']')).classList.add('modal--is-open');
    });
  }
  
  for (let i = 0; i < modalCloseButtons.length; i++) {
    const modalCloseButton = modalCloseButtons[i];
    modalCloseButton.addEventListener('click', e => {
      body.classList.remove('has-modal-open');
      e.target.closest('.modal').classList.remove('modal--is-open');
    });
  }
  
  for (let i = 0; i < modal.length; i++) {
    const modals = modal[i];
    document.addEventListener('keydown', e => {
      if (e.keyCode === 27) {
        modals.classList.remove('modal--is-open')
      }
    })
    modals.addEventListener('click', e => {
      e.target.classList.remove('modal--is-open')
    })
  }
.modal {
  display: none;
  justify-content: center;
  align-items: center;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  max-height: calc(100% - 48px);
  background: rgba(0, 0, 0, 0.45);
  z-index: 90;
}

.modal__header {
  position: relative;
  border-radius: 4px 4px 0 0;
  background-color: white;
  width: 100%;
  min-height: 60px;
  overflow: auto;
}

.modal__body {
  position: relative;
  width: calc(100% - 48px);
  max-width: 900px;
  max-height: calc(100% - 48px);
  overflow: hidden;
  border-radius: 4px;
  max-height: 700px;
  background: white;
}

.modal__content {
  padding: 0 40px 40px;
  overflow: auto;
  height: 100px;
}

.modal--is-open {
  display: flex;
}

.has-modal-open {
  overflow-y: hidden;
}


.modal__close {
  position: absolute;
  top: 32px;
  right: 12px;
  transform: translateY(-50%);
  width: 56px;
  height: 56px;
  padding: 0;
}
<button class="button" data-open-modal="open-modal-1">Open modal</button>

<div class="modal" data-open-modal="open-modal-1">
  <div class="modal__body">
    <div class="modal__header">
      <button class="modal__close" data-close-modal>X</button>
    </div>
    <div class="modal__content">
      My modal
    </div>
  </div>
</div>


推荐阅读