当用香草 javascript 关闭模态时,从正文中删除 class
Remove class from body when modal is closed with vanilla javascript
我的页面上有多个模态框,当单击相应按钮时会打开这些模态框。
当模式打开时,它会将 class .has-modal-open
添加到正文以防止页面滚动。
问题是当我关闭模态时 class 没有从正文标签中删除。我试过 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>
你的错误只是说
"message": "Uncaught TypeError: Cannot read properties of null (reading 'classList')",
这意味着在您的代码中 body
代表 null
发生这种情况可能有多种原因
一个可能是你没有以正确的方式访问它
您的代码有 2 个问题:
body.classList.remove('has-modal-open');
应该在关闭按钮的 eventListener 内部调用,但您之前调用了它。
modalOpenButtons = document.querySelectorAll('[data-open-modal]');
不仅选择按钮,还选择具有属性 data-open-modal
的模式。当您单击关闭按钮时,模式也会被单击,因此在您的情况下调用附加到 modalOpenButtons
的 eventListener。您应该只将按钮放在 modalOpenButtons
中,例如:
const modalOpenButtons = document.querySelectorAll('button[data-open-modal]');
我在下面制作了一个片段,您可以在其中看到 class 正确地得到 added/removed
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>
我的页面上有多个模态框,当单击相应按钮时会打开这些模态框。
当模式打开时,它会将 class .has-modal-open
添加到正文以防止页面滚动。
问题是当我关闭模态时 class 没有从正文标签中删除。我试过 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>
你的错误只是说
"message": "Uncaught TypeError: Cannot read properties of null (reading 'classList')",
这意味着在您的代码中 body
代表 null
发生这种情况可能有多种原因
一个可能是你没有以正确的方式访问它
您的代码有 2 个问题:
body.classList.remove('has-modal-open');
应该在关闭按钮的 eventListener 内部调用,但您之前调用了它。modalOpenButtons = document.querySelectorAll('[data-open-modal]');
不仅选择按钮,还选择具有属性data-open-modal
的模式。当您单击关闭按钮时,模式也会被单击,因此在您的情况下调用附加到modalOpenButtons
的 eventListener。您应该只将按钮放在modalOpenButtons
中,例如:
const modalOpenButtons = document.querySelectorAll('button[data-open-modal]');
我在下面制作了一个片段,您可以在其中看到 class 正确地得到 added/removed
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>