Home > Net >  Javascript - Remove class with document.addEventListener not working
Javascript - Remove class with document.addEventListener not working

Time:06-28

I'm trying to close dropdown menu by clicking on the body or whatever. To do this I'm using document.addEventListener but it doesn't work.

By doing several tests I managed to get the code to work by adding a div that simulates a "body". So instead of document.addEventListener I wrote document.getElementById ("container_test"). AddEventListener.

the problem is that when there is no getElement it doesn't work. I can't understand what I'm wrong, can someone help me?

Here are two examples:

Not Working Code

var usermenu = document.querySelector(".user_menu_button");

function userMenu() {
  var x = document.getElementById("mts_menu");
  if (x.classList.toggle("show")) {
    usermenu.innerHTML = '<i ></i><span >Account</span>';
  } else {
    usermenu.innerHTML = '<i ></i><span >Account</span>';
  }
}

const closing = document.querySelector("#mts_menu");

document.addEventListener("click", (evt) => {
  if (!evt.target.closest("#mts_menu")) closing.classList.remove("show");
});
/*Button Toggle Menu*/

.user_menu_button {
  display: flex;
  align-content: center;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 32px;
  background: #3D4350!important;
  border-radius: 4px;
  padding: 12px;
  font-size: 14px!important;
  line-height: 2;
}

.icn_button {
  margin: 0;
}

.icn_button:before,
.icn_button:after {
  margin: 0;
}

.txt_button {
  margin-left: 10px;
  color: #fff;
  font-size: 14px;
  font-weight: 400;
}


/*Items menu*/

.user_menu {
  display: flex;
  flex-direction: column;
}

.user_menu.header {
  padding: 15px 15px;
}


/*Menu header info*/

.display.name {
  font-size: 14px;
  font-weight: 500;
  color: #303238;
  line-height: 1.5;
}

.display.mail {
  font-size: 13px;
  color: #1E70EB;
  line-height: 1.5;
}

hr.divider-menu {
  border-top: 1px solid #e0e0e0;
}


/*Text Link css*/

.mnu_margin {
  margin: 7px 0;
}

.user_menu.item>a {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding: 8px 15px;
  color: #212629;
}

.user_menu.item:hover>a {
  color: #fff;
  background: #1E70EB;
  transition: all 0.2s;
}

.user_menu.item>a .link_text {
  font-size: 14px;
  color: #212629;
}

.user_menu.item:hover>a .link_text {
  color: #fff;
}


/*Icon Items Menu*/

.icn_menu:before,
.icon_menu:after {
  margin: 0px;
  padding: 0px;
  font-size: 16px
}

.icn_menu {
  margin-right: 10px;
  display: flex !important;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
}


/* User Menu For header website */

.mts_menu_container {
  display: flex;
  flex-direction: column;
  align-content: flex-end;
  align-items: flex-end;
}

.dropdown_box {
  position: absolute;
  margin-top: 20px;
}

.mts_dropdown_content {
  background-color: #fff;
  min-width: 160px;
  width: 240px;
  border-radius: 6px;
  overflow-x: hidden;
  overflow-y: hidden;
  box-shadow: rgba(0, 0, 0, 0.15) 0px 5px 15px 0px;
  z-index: 999;
  position: relative;
  visibility: hidden;
  opacity: 0;
  top: 50px;
  height: 0;
  transition: visibility 0.2s, max-height 0.2s, opacity 0.2s, top 0.2s, height 0.2s;
}

.mts_dropdown_content.show {
  height: 100%;
  visibility: visible;
  opacity: 1;
  top: 0;
  transition: visibility 0.2s, max-height 0.2s, opacity 0.2s, top 0.2s, height 0.2s;
}
<button onclick="userMenu()" >
     <i ></i>
     <span >Account</span>
</button>

<div >
  <div >

    <div id="mts_menu" >
      <div >
        <span >Ciao [display_name]</span>
        <span >[display_email]</span>
      </div>

      <hr >

      <div >
        <div >
          <a href="/account">
            <i ></i>
            <span >Dashboard</span>
          </a>
        </div>

        <div >
          <a href="ordini">
            <i ></i>
            <span >I miei ordini</span>
          </a>
        </div>

        <div >
          <a href="libreria">
            <i ></i>
            <span >Downloads</span>
          </a>
        </div>

        <div >
          <a href="impostazioni">
            <i ></i>
            <span >Impostazioni</span>
          </a>
        </div>

        <div >
          <a href="wp-login.php?action=logout">
            <i ></i>
            <span >Logout</span>
          </a>
        </div>
      </div>

    </div>
  </div>
</div>

Working Code

var usermenu = document.querySelector(".user_menu_button");

function userMenu() {
  var x = document.getElementById("mts_menu");
  if (x.classList.toggle("show")) {
    usermenu.innerHTML = '<i ></i><span >Account</span>';
  } else {
    usermenu.innerHTML = '<i ></i><span >Account</span>';
  }
}

const closing = document.querySelector("#mts_menu");

document.getElementById("container_test").addEventListener("click", (evt) => {
  if (!evt.target.closest("#mts_menu")) closing.classList.remove("show");
});
#container_test {
  margin-top: 20px;
  border: 1px solid;
  padding: 20px;
}


/*Button Toggle Menu*/

.user_menu_button {
  display: flex;
  align-content: center;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 32px;
  background: #3D4350!important;
  border-radius: 4px;
  padding: 12px;
  font-size: 14px!important;
  line-height: 2;
}

.icn_button {
  margin: 0;
}

.icn_button:before,
.icn_button:after {
  margin: 0;
}

.txt_button {
  margin-left: 10px;
  color: #fff;
  font-size: 14px;
  font-weight: 400;
}


/*Items menu*/

.user_menu {
  display: flex;
  flex-direction: column;
}

.user_menu.header {
  padding: 15px 15px;
}


/*Menu header info*/

.display.name {
  font-size: 14px;
  font-weight: 500;
  color: #303238;
  line-height: 1.5;
}

.display.mail {
  font-size: 13px;
  color: #1E70EB;
  line-height: 1.5;
}

hr.divider-menu {
  border-top: 1px solid #e0e0e0;
}


/*Text Link css*/

.mnu_margin {
  margin: 7px 0;
}

.user_menu.item>a {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding: 8px 15px;
  color: #212629;
}

.user_menu.item:hover>a {
  color: #fff;
  background: #1E70EB;
  transition: all 0.2s;
}

.user_menu.item>a .link_text {
  font-size: 14px;
  color: #212629;
}

.user_menu.item:hover>a .link_text {
  color: #fff;
}


/*Icon Items Menu*/

.icn_menu:before,
.icon_menu:after {
  margin: 0px;
  padding: 0px;
  font-size: 16px
}

.icn_menu {
  margin-right: 10px;
  display: flex !important;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
}


/* User Menu For header website */

.mts_menu_container {
  display: flex;
  flex-direction: column;
  align-content: flex-end;
  align-items: flex-end;
}

.dropdown_box {
  position: absolute;
  margin-top: 20px;
}

.mts_dropdown_content {
  background-color: #fff;
  min-width: 160px;
  width: 240px;
  border-radius: 6px;
  overflow-x: hidden;
  overflow-y: hidden;
  box-shadow: rgba(0, 0, 0, 0.15) 0px 5px 15px 0px;
  z-index: 999;
  position: relative;
  visibility: hidden;
  opacity: 0;
  top: 50px;
  height: 0;
  transition: visibility 0.2s, max-height 0.2s, opacity 0.2s, top 0.2s, height 0.2s;
}

.mts_dropdown_content.show {
  height: 100%;
  visibility: visible;
  opacity: 1;
  top: 0;
  transition: visibility 0.2s, max-height 0.2s, opacity 0.2s, top 0.2s, height 0.2s;
}
<button onclick="userMenu()" >
     <i ></i>
     <span >Account</span>
</button>

<div >
  <div >

    <div id="mts_menu" >
      <div >
        <span >Ciao [display_name]</span>
        <span >[display_email]</span>
      </div>

      <hr >

      <div >
        <div >
          <a href="/account">
            <i ></i>
            <span >Dashboard</span>
          </a>
        </div>

        <div >
          <a href="ordini">
            <i ></i>
            <span >I miei ordini</span>
          </a>
        </div>

        <div >
          <a href="libreria">
            <i ></i>
            <span >Downloads</span>
          </a>
        </div>

        <div >
          <a href="impostazioni">
            <i ></i>
            <span >Impostazioni</span>
          </a>
        </div>

        <div >
          <a href="wp-login.php?action=logout">
            <i ></i>
            <span >Logout</span>
          </a>
        </div>
      </div>

    </div>
  </div>
</div>

<div id="container_test">container test</div>

CodePudding user response:

When you click on the button to open the menu, the menu is opened, then the event bubbles out to document. Since the button isn't inside the menu, the menu closes.

Yuo should use event.stopPropagation in the button code to prevent this.

var usermenu = document.querySelector(".user_menu_button");

function userMenu(event) {
  event.stopPropagation();
  var x = document.getElementById("mts_menu");
  if (x.classList.toggle("show")) {
    usermenu.innerHTML = '<i ></i><span >Account</span>';
  } else {
    usermenu.innerHTML = '<i ></i><span >Account</span>';
  }
}

const closing = document.querySelector("#mts_menu");

document.addEventListener("click", (evt) => {
  if (!evt.target.closest("#mts_menu")) closing.classList.remove("show");
});
/*Button Toggle Menu*/

.user_menu_button {
  display: flex;
  align-content: center;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 32px;
  background: #3D4350!important;
  border-radius: 4px;
  padding: 12px;
  font-size: 14px!important;
  line-height: 2;
}

.icn_button {
  margin: 0;
}

.icn_button:before,
.icn_button:after {
  margin: 0;
}

.txt_button {
  margin-left: 10px;
  color: #fff;
  font-size: 14px;
  font-weight: 400;
}


/*Items menu*/

.user_menu {
  display: flex;
  flex-direction: column;
}

.user_menu.header {
  padding: 15px 15px;
}


/*Menu header info*/

.display.name {
  font-size: 14px;
  font-weight: 500;
  color: #303238;
  line-height: 1.5;
}

.display.mail {
  font-size: 13px;
  color: #1E70EB;
  line-height: 1.5;
}

hr.divider-menu {
  border-top: 1px solid #e0e0e0;
}


/*Text Link css*/

.mnu_margin {
  margin: 7px 0;
}

.user_menu.item>a {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding: 8px 15px;
  color: #212629;
}

.user_menu.item:hover>a {
  color: #fff;
  background: #1E70EB;
  transition: all 0.2s;
}

.user_menu.item>a .link_text {
  font-size: 14px;
  color: #212629;
}

.user_menu.item:hover>a .link_text {
  color: #fff;
}


/*Icon Items Menu*/

.icn_menu:before,
.icon_menu:after {
  margin: 0px;
  padding: 0px;
  font-size: 16px
}

.icn_menu {
  margin-right: 10px;
  display: flex !important;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
}


/* User Menu For header website */

.mts_menu_container {
  display: flex;
  flex-direction: column;
  align-content: flex-end;
  align-items: flex-end;
}

.dropdown_box {
  position: absolute;
  margin-top: 20px;
}

.mts_dropdown_content {
  background-color: #fff;
  min-width: 160px;
  width: 240px;
  border-radius: 6px;
  overflow-x: hidden;
  overflow-y: hidden;
  box-shadow: rgba(0, 0, 0, 0.15) 0px 5px 15px 0px;
  z-index: 999;
  position: relative;
  visibility: hidden;
  opacity: 0;
  top: 50px;
  height: 0;
  transition: visibility 0.2s, max-height 0.2s, opacity 0.2s, top 0.2s, height 0.2s;
}

.mts_dropdown_content.show {
  height: 100%;
  visibility: visible;
  opacity: 1;
  top: 0;
  transition: visibility 0.2s, max-height 0.2s, opacity 0.2s, top 0.2s, height 0.2s;
}
<button onclick="userMenu(event)" >
     <i ></i>
     <span >Account</span>
</button>

<div >
  <div >

    <div id="mts_menu" >
      <div >
        <span >Ciao [display_name]</span>
        <span >[display_email]</span>
      </div>

      <hr >

      <div >
        <div >
          <a href="/account">
            <i ></i>
            <span >Dashboard</span>
          </a>
        </div>

        <div >
          <a href="ordini">
            <i ></i>
            <span >I miei ordini</span>
          </a>
        </div>

        <div >
          <a href="libreria">
            <i ></i>
            <span >Downloads</span>
          </a>
        </div>

        <div >
          <a href="impostazioni">
            <i ></i>
            <span >Impostazioni</span>
          </a>
        </div>

        <div >
          <a href="wp-login.php?action=logout">
            <i ></i>
            <span >Logout</span>
          </a>
        </div>
      </div>

    </div>
  </div>
</div>

CodePudding user response:

  • In your "not working code" you need to exclude the button that show the menu too.
document.addEventListener("click", (evt) => {
      if (!evt.target.closest("#mts_menu")  && !evt.target.closest('.user_menu_button')) closing.classList.remove("show");
    });
  • Related