在前端开发菜单的时候,经常遇到鼠标一移出菜单项的范围,子菜单马上消失,导致用户很难选择到想要的菜单。
jQuery-menu-aim
menu-aim is a jQuery plugin for dropdown menus that can differentiate between a user trying hover over a dropdown item vs trying to navigate into a submenu's contents.
This problem is normally solved using timeouts and delays. menu-aim tries to solve this by detecting the direction of the user's mouse movement. This can make for quicker transitions when navigating up and down the menu. The experience is hopefully similar to amazon.com/'s "Shop by Department" dropdown.
How did Amazon get away without using a delay?
It’s easy to move the cursor from Amazon’s main dropdown to its submenus. You won’t run into the bootstrap bug. They get away with this by detecting the direction of the cursor’s path.
https://github.com/kamens/jQuery-menu-aim/blob/master/README.md
请看如下示例代码:
1. html 文件中定义了菜单标签:
<div class="page-sidebar care-gradients" id="sidebar">
<ul class="nav sidebar-menu" role="menu" id="page-sidebar-menu">
<li ng-repeat="menu in menus" ng-class="{active: isActive(menu)}"
data-submenu-id="submenu-{{menu.id}}" on-finish-render="ngRepeatFinished">
<a href="{{menu.path}}" ng-class="{'menu-dropdown': menu.submenus.length > 0}" ng-if="menu.id!='blank'">
<img src="/images/{{menu.src}}" class="{{menu.class}}" alt="" ng-click="openCfgPage(menu.defaultpath)">
<span class="menu-text"> {{menu.title}} </span>
<i class="menu-expand white" ng-if="menu.submenus.length > 0"></i>
</a>
<a ng-if="menu.id=='blank'" class="blank-submenu-row"></a>
<ul id="submenu-{{menu.id}}" class="submenu popover" ng-if="menu.submenus.length > 0">
<li ng-repeat="submenu in menu.submenus" ng-class="{active: isActive(submenu)}"
ng-if="submenu.authorizedRole == undefined || isAuthorized(submenu.authorizedSymbol, submenu.authorizedRole)">
<a href="/#{{submenu.path}}">
<span class="menu-text"> {{submenu.title}}</span>
</a>
</li>
</ul>
</li>
</ul>
</div>
2. index.html文件中引用 jQuery-menu-aim插件
<script src="scripts/vendors/jQuery-menu-aim-master/jquery.menu-aim.js"></script>
3.controller中处理菜单的显示和隐藏:
$scope.$on('ngRepeatFinished', function () {
var $menu = $("#page-sidebar-menu");
$menu.menuAim({
activate: function (row) {
var b = $("#sidebar").hasClass("menu-compact");
if(b) {
var $row = $(row),
submenuId = $row.data("submenuId"),
$submenu = $("#" + submenuId);
$submenu.css({display: "block"});
}
},
deactivate: function (row) {
var b = $("#sidebar").hasClass("menu-compact");
if(b) {
var $row = $(row),
submenuId = $row.data("submenuId"),
$submenu = $("#" + submenuId);
$submenu.css("display", "none");
}
},
exitMenu: function (){
return true;
}
});
});
row 代表的是li对象,即一级菜单项
<li ng-repeat="menu in menus"
通过html中ul标签设置data-submenu-id, 及<ul id="submenu-{{menu.id}}",可以取到li下面的子菜单,从而设置display值来控制子菜单的显示和隐藏。
timeout及delay的处理请看源码jquery.menu-aim.js中的activationDelay()函数。