Home » vue » mouseleave event fires late in vue.js

mouseleave event fires late in vue.js

Posted by: admin November 26, 2021 Leave a comment

Questions:

I have a simple sidebar designed in HTML and I have developed a script where the sidebar closes and opens when the mouse enters and mouse leaves respectively.

You can check out the DEMO here.

I have used Vue.js instance for the whole sidebar, everything works perfectly except when the mouse hovers any of the items in the side bar then when the mouse leaves, the closing of the side bar is very slow.

Answers:

You should use mouseenter instead of mouseover ..

<div id="custom-erp-id-side-nav" class="custom-erp-side-nav" @mouseenter="openSideBar" @mouseleave="closeSideBar">

Codepen

###

You can change the animate time, for example set 50

closeSideBar: function() {
  $("#custom-erp-id-side-nav")
    .off()
    .animate({ left: "-230px" }, 50);
}

###

What is happening is that you’re queueing up a lot of events. In some situations, you can get an opening-and-closing loop that keeps going until you move your mouse. This happens even if you use mouseenter instead of mouseover.

You can have your open and close routines each set a gatekeeper variable to ensure that they don’t try multiple opens (or closes). In the complete parameter of animate, you unset the gatekeeper variable.

    openSideBar: function() {
      if (!this.opening) {
        this.opening = true;
        $("#custom-erp-id-side-nav")
          .off()
          .animate({
            left: "0px"
          }, null, null, () => {
            this.opening = false;
          });
      }
    },
    closeSideBar: function() {
      if (!this.closing) {
        this.closing = true;
        $("#custom-erp-id-side-nav")
          .off()
          .animate({
            left: "-230px"
          }, null, null, () => {
            this.closing = false;
          });
      }
    }

// vue instance for the sidebar menu
var erp_custom_side_bar = new Vue({
  el: "#custom-erp-id-side-nav",
  data: {},
  methods: {
    //function to close/open the child elements
    //when the parent menu is clicked.
    toggleOpenChild: function(event) {
      var currentParent = $(event.currentTarget)
        .find(".custom-erp-menu-parent")
        .text();
      var childListID = currentParent.toLowerCase().replace(/ /g, "-");
      $(".custom-erp-menu-list > ul")
        .not($("#" + childListID + "-child"))
        .slideUp()
        .removeClass("custom-erp-menu-child-open");
      if ($("#" + childListID + "-child").is(":hidden")) {
        $("#" + childListID + "-child")
          .slideDown(300)
          .toggleClass("custom-erp-menu-child-open");
      } else {
        $("#" + childListID + "-child")
          .slideUp(300)
          .toggleClass("custom-erp-menu-child-open");
      }
    },
    openSideBar: function() {
      if (!this.opening) {
        this.opening = true;
        $("#custom-erp-id-side-nav")
          .off()
          .animate({
            left: "0px"
          }, null, null, () => {
            this.opening = false;
          });
      }
    },
    closeSideBar: function() {
      if (!this.closing) {
        this.closing = true;
        $("#custom-erp-id-side-nav")
          .off()
          .animate({
            left: "-230px"
          }, null, null, () => {
            this.closing = false;
          });
      }
    }
  }
});
.custom-erp-side-nav {
  height: 100%;
  width: 240px;
  position: fixed;
  z-index: 1;
  top: 56px;
  left: 0;
  background-color: #2b333e;
  overflow-x: hidden;
  padding-top: 20px;
  left: -230px;
}

.custom-erp-side-nav-open {
  left: 0;
}

.custom-erp-menu-list a {
  padding: 10px 5px 10px 40px;
  text-decoration: none;
  letter-spacing: 0.3px;
  font-size: 16px;
  color: #aeb7c2;
  display: block;
}

.custom-erp-menu-list>a {
  padding-left: 20px;
}

.custom-erp-menu-list a:hover {
  color: #f1f1f1 !important;
  background-color: rgb(56, 65, 74);
}

.custom-erp-menu-list a:hover .custom-erp-module-list-icon {
  filter: brightness(0) invert(1);
}

.custom-erp-module-list-icon {
  margin-right: 10px;
}

.custom-erp-menu-child-dropdown {
  display: none;
  background-color: #252c35;
  border-left: 3px solid #3cabfe;
}

.custom-erp-menu-child-dropdown>a:hover {
  background-color: rgb(56, 65, 74);
}

#custom-erp-menu-lists {
  padding-left: 0px !important;
}

.custom-erp-menu-child-open {
  display: block;
}
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="custom-erp-id-side-nav" class="custom-erp-side-nav" @mouseover="openSideBar" @mouseleave="closeSideBar">

  <nav id="custom-erp-menu-nav">
    <ul id="custom-erp-menu-lists">
      <li class="custom-erp-menu-list" v-on:click="toggleOpenChild">
        <a href="#">
          <span>
							<img src="assets/images/dollar-bills.svg" class="custom-erp-module-list-icon custom-erp-user-icons" width="18" height="18" alt="">
						</span>
          <span class="custom-erp-menu-parent">Purchase Order</span>
        </a>
        <ul class="nav custom-erp-menu-child-dropdown" id="purchase-order-child">
          <li><a href="page-profile.html" class="custom-erp-menu-child">Profile</a></li>
          <li><a href="page-login.html" class="custom-erp-menu-child">Login</a></li>
          <li><a href="page-lockscreen.html" class="custom-erp-menu-child">Lockscreen</a></li>
        </ul>
      </li>

      <li class="custom-erp-menu-list" v-on:click="toggleOpenChild">
        <a href="#">
          <span>
							<img src="assets/images/dollar-bills.svg" class="custom-erp-module-list-icon custom-erp-user-icons" width="18" height="18" alt="">
						</span>
          <span class="custom-erp-menu-parent">Expense</span>
        </a>
        <ul class="nav custom-erp-menu-child-dropdown" id="expense-child">
          <li><a href="page-profile.html" class="custom-erp-menu-child">Profile</a></li>
          <li><a href="page-login.html" class="custom-erp-menu-child">Login</a></li>
          <li><a href="page-lockscreen.html" class="custom-erp-menu-child">Lockscreen</a></li>
        </ul>
      </li>

    </ul>
  </nav>

</div>