I have a button
, in my markup called .open-video
.
Clicking .open-video
opens up a modal which then contains another button .close--modal
. The code for the modal (which includes the markup for .modal--close
) is added when the .open-video
button is clicked.
Now, I'm aware that the EventListener
for .modal--close
needs to exist after the markup is added to the DOM
on the first EventListener
for .open-video
. But, doing this isn't doing anything at the moment, I instead get the error message Cannot read properties of null (reading 'addEventListener')
and I believe this is because the DOMContentLoaded
event was already fired at this point.
Currently, when clicking .modal--close
, I just want to do a simple console.log("test");
.
See my demo below:
if (document.readyState === "complete") {
ready();
} else {
document.addEventListener("DOMContentLoaded", ready);
}
function ready() {
let video_btn = document.querySelector(".open-video");
let close_btn = document.querySelector(".modal--close");
let modal = document.querySelector(".modal");
console.log(close_btn);
if (video_btn) {
video_btn.addEventListener("click", function(e) {
e.preventDefault();
// get data
var triggerURL = this.getAttribute("href");
var triggerID = this.getAttribute("data-modal");
// update modal attributes with trigger data
modal.setAttribute("data-video", triggerURL);
modal.setAttribute("id", triggerID);
var modalID = '#' triggerID;
modal.classList.add("modal--open");
var html = '<a href="#" ></a><div ><iframe width="640" height="360" src="' triggerURL '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe></div><div ></div>';
// modal.insertAdjacentHTML('beforeend', html);
modal.innerHTML = html;
close_btn.addEventListener("click", function(e) {
e.preventDefault();
console.log("test");
});
return false;
});
}
}
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
overflow: hidden;
display: none;
padding: 70px 80px;
}
.modal--close {
position: fixed;
right: 50%;
top: 32px;
width: 16px;
height: 16px;
z-index: 999999;
pointer-events: auto !important;
}
.modal--close:hover:before,
.modal--close:hover:after {
background-color: #F15A40;
}
.modal--close:before,
.modal--close:after {
content: "";
position: absolute;
left: 15px;
height: 16px;
width: 2px;
background-color: #FFFFFF;
}
.modal--close:before {
transform: rotate(45deg);
}
.modal--close:after {
transform: rotate(-45deg);
}
.modal--open {
display: block;
}
.modal .modal__wrapper {
position: relative;
top: 50%;
transform: translateY(-50%);
max-height: 100%;
overflow: hidden;
z-index: 150;
}
.modal .modal__wrapper:before {
content: "";
display: block;
padding-top: 56.25%;
}
.modal .modal__wrapper iframe,
.modal .modal__wrapper video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
outline: none;
}
.modal .modal__overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000000;
}
<a data-modal="video--1" href="https://www.youtube.com/embed/NpEaa2P7qZI">Click me</a>
<div >
<div ></div>
<div ></div>
</div>
How can I get my .modal--close
button to print the log? Where am I going wrong?
CodePudding user response:
Because you call closeElement
before you create closeElement
.
You can call this element after creating.
video_btn.addEventListener("click", function(e) {
e.preventDefault();
// ... codes
// modal.insertAdjacentHTML('beforeend', html);
modal.innerHTML = html;
let close_btn = document.querySelector(".modal--close");
close_btn.addEventListener("click", function(e) {
e.preventDefault();
console.log("test");
});
return false;
});
CodePudding user response:
You can't document.querySelect an element before it's added to the DOM, you should move the line of
let close_btn = document.querySelector(".modal--close"); // here
to inside the video_btn.addEventListener callback function after you've added the element .modal--close
to the DOM.
if (document.readyState === "complete") {
ready();
} else {
document.addEventListener("DOMContentLoaded", ready);
}
function ready() {
let video_btn = document.querySelector(".open-video");
let modal = document.querySelector(".modal");
if (video_btn) {
video_btn.addEventListener("click", function(e) {
e.preventDefault();
// get data
var triggerURL = this.getAttribute("href");
var triggerID = this.getAttribute("data-modal");
// update modal attributes with trigger data
modal.setAttribute("data-video", triggerURL);
modal.setAttribute("id", triggerID);
var modalID = '#' triggerID;
modal.classList.add("modal--open");
var html = '<a href="#" ></a><div ><iframe width="640" height="360" src="' triggerURL '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe></div><div ></div>';
// modal.insertAdjacentHTML('beforeend', html);
modal.innerHTML = html;
let close_btn = document.querySelector(".modal--close"); // here
close_btn.addEventListener("click", function(e) {
e.preventDefault();
console.log("test");
});
return false;
});
}
}
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
overflow: hidden;
display: none;
padding: 70px 80px;
}
.modal--close {
position: fixed;
right: 50%;
top: 32px;
width: 16px;
height: 16px;
z-index: 999999;
pointer-events: auto !important;
}
.modal--close:hover:before,
.modal--close:hover:after {
background-color: #F15A40;
}
.modal--close:before,
.modal--close:after {
content: "";
position: absolute;
left: 15px;
height: 16px;
width: 2px;
background-color: #FFFFFF;
}
.modal--close:before {
transform: rotate(45deg);
}
.modal--close:after {
transform: rotate(-45deg);
}
.modal--open {
display: block;
}
.modal .modal__wrapper {
position: relative;
top: 50%;
transform: translateY(-50%);
max-height: 100%;
overflow: hidden;
z-index: 150;
}
.modal .modal__wrapper:before {
content: "";
display: block;
padding-top: 56.25%;
}
.modal .modal__wrapper iframe,
.modal .modal__wrapper video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
outline: none;
}
.modal .modal__overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000000;
}
<a data-modal="video--1" href="https://www.youtube.com/embed/NpEaa2P7qZI">Click me</a>
<div >
<div ></div>
<div ></div>
</div>