Dynamically create a modal - vanilla JS

I would like to create a modal, which means that when I click on a specific nav link, instead of it redirecting me to its page, it will only make the modal appear, no matter where I am on the site at that moment.

I am making a page with WordPress, meaning that I do not have access to the HTML file, which is why I am looking to create one dynamically. I know the structure of the modal is supposed to be the following:

<a href="">Newsletter</a>
<div id="modal" class="modal">
  <div class="modalContent">
    <span class="close">&times;</span>
    <h2></h2>
    <p></p>
  </div>
</div>

And then grabbing these HTML elements in the JS file and a function both opening/closing the modal, etc.

However, I can't seem to do it with JS only since I am having a hard time defining that hierarchy that is easy to achieve in HTML by placing spans into divs and so on. Any help is greatly appreciated!

function newsletterModal() {
    const btn = document.querySelector("#menu-item-1706");
    btn.addEventListener("click", (e) => {
    e.preventDefault(); 

    // create modal
    const modal = document.createElement("div");
    modal.classList.add("modal");
    // create modal content
    const modalContent = document.createElement("div");
    modalContent.classList.add("modalContent");
    const modalContentText = document.createElement("p");
    modalContentText.textContent = "...";
    // create X
    const span = document.createElement("span");
    span.classList.add("close");
    span.innerHTML = "&times;";

    btn.onclick = function () {
      modal.style.display = "block";
    };
    span.onclick = function () {
      modal.style.display = "none";
    };
    window.onclick = function (event) {
      if (event.target == modal) {
        modal.style.display = "none";
      }
    };
  });
 document.body.appendChild(modal);
}

Upvotes: 0

Views: 5772

Answers (1)

Andrey Kostenko
Andrey Kostenko

Reputation: 382

To make your life easier you could've just tried to create some div node and then set inner contents with innerHTML. I.e.

const modal = document.createElement('div');
modal.classList.add('modal');
modal.id = 'modal';
modal.hidden = true;

modal.innerHTML = `
  <div class="modalContent">
    <span class="close">&times;</span>
    <h2></h2>
    <p></p>
  </div>
`;

modal.querySelector('.close').addEventListener('click', () => { modal.hidden = true; });

querySelector helps to find elements within the parent node, very helpful in cases like this.

Also there are a few words about hidden attribute. In addition, you may take a look at relatively new <dialog> element that is designed right for modal purposes.

Upvotes: 3

Related Questions