简体   繁体   中英

Flickering dropdown menu on hover

I needed to write my dropdown menu in javascript because there are several aspects that cannot be done with CSS. I came across this bug when I hover over my menu item, submenu pops up, I click on an element and it starts flickering.

I know it's because I'm still within that element which triggers mouseenter again. What can I do in this case?

I don't want to set up a timer to wait and then reopen the dropdown menu again...

 angular.module('app',[]).controller('mainCtrl', function() { var vm = this; vm.showSubmenu = false; vm.toggleMenu = function() { vm.showSubmenu =.vm;showSubmenu. } vm.changeState = function() { //$state;go('blablabla'). vm;showSubmenu = false; } })
 .submenu { background: lightblue; position: absolute; top: 45px; left: 0; padding: 20px; line-height: 20px; visibility: hidden; }.submenu.active-sub { visibility: visible; }.menu { list-style-type: none; } ul li { background: grey; line-height: 30px; width: 150px; }.submenu ul { position: relative; float: left; left: 0; }
 <html ng-app="app"> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.min.js"></script> </head> <body> <div ng-controller="mainCtrl as vm"> <ul class="menu"> <li ng-mouseenter="vm.toggleMenu()" ng-mouseleave="vm.toggleMenu()">OPEN SUBMENU <div class="submenu" ng-class="{'active-sub':vm.showSubmenu}"> <ul> <li><a href="#" ng-click="vm.changeState()">Link 1</a></li> <li><a href="#" ng-click="vm.changeState()">Link 2</a></li> <li><a href="#" ng-click="vm.changeState()">Link 3</a></li> </ul> </div> </li> </ul> </div> </body> </html>

Why don't you just add hideMenu() and showMenu() functions, since that is what you want. You want to hide the menu in mouseleave event and show the menu in mouseenter.

If you don't want to write more code within the click event you could also call hideMenu() instead of a new function.

Edit (explanation of the problem)

It's because of the firering events. So basically what happens is the following.

  1. Initially vm.showSubmenu = false
  2. mouseenter -> vm.showSubmenu =.vm;showSubmenu; // gets true vm.showSubmenu =.vm;showSubmenu; // gets true
  3. click on a link -> method call changeState() sets vm.showSubmenu = false;
  4. the submenu gets hidden.
  5. the mouseleave event gets fired and since you set the vm.showSubmenu to false within your changeState() method, the mouseleave event negates the variable, so the submenu gets visible again, the mouseenter gets fired, the variable gets false and so on...

 angular.module('app',[]).controller('mainCtrl', function() { var vm = this; vm.showSubmenu = false; vm.hideMenu = function() { vm.showSubmenu = false; } vm.showMenu = function() { vm.showSubmenu = true; } vm.click = function(){ vm.hideMenu(); } })
 .submenu { background: lightblue; position: absolute; top: 45px; left: 0; padding: 20px; line-height: 20px; visibility: hidden; }.submenu.active-sub { visibility: visible; }.menu { list-style-type: none; } ul li { background: grey; line-height: 30px; width: 150px; }.submenu ul { position: relative; float: left; left: 0; }
 <html ng-app="app"> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.min.js"></script> </head> <body> <div ng-controller="mainCtrl as vm"> <ul class="menu"> <li ng-mouseenter="vm.showMenu()" ng-mouseleave="vm.hideMenu()">OPEN SUBMENU <div class="submenu" ng-class="{'active-sub':vm.showSubmenu}"> <ul> <li><a href="#" ng-click="vm.click()">Link 1</a></li> <li><a href="#" ng-click="vm.click()">Link 2</a></li> <li><a href="#" ng-click="vm.click()">Link 3</a></li> </ul> </div> </li> </ul> </div> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM