鼠标悬停时打开角度材质菜单

Posted

技术标签:

【中文标题】鼠标悬停时打开角度材质菜单【英文标题】:Angular material menu opening on mouse hover 【发布时间】:2016-01-28 11:16:30 【问题描述】:

我正在使用 Angular Material 菜单栏来显示菜单和每个菜单项下的子菜单。我添加了 ng-click 事件来打开子菜单。但是菜单仍然在鼠标悬停在父菜单项上时打开。不仅如此,因为我有两个子菜单,对于第一个子菜单项,子菜单在鼠标悬停时打开,但第二个子菜单在鼠标悬停时未打开。我如何在鼠标悬停时阻止此菜单打开。我试图在父菜单项上的 mouseenter 上停止事件传播。但是在打开第二个子菜单时,第一个子菜单并没有被隐藏。请帮我解决一下。

<div ng-controller="DemoBasicCtrl as ctrl" ng-cloak="" class="menuBardemoBasicUsage" ng-app="MyApp">

    <md-menu-bar>
      <md-menu>
        <button ng-click="$mdOpenMenu()">
          File
        </button>
        <md-menu-content>
          <md-menu-item>
            <md-menu>
              <md-button ng-click="$mdOpenMenu()">New</md-button>
              <md-menu-content>
                <md-menu-item><md-button ng-click="ctrl.sampleAction('New Document', $event)">Document</md-button></md-menu-item>
              </md-menu-content>
            </md-menu>
          </md-menu-item>
                        <md-menu-item>
            <md-menu>
              <md-button ng-click="$mdOpenMenu()">New</md-button>
              <md-menu-content>
                <md-menu-item><md-button ng-click="ctrl.sampleAction('New Document', $event)">Document</md-button></md-menu-item>
              </md-menu-content>
            </md-menu>
          </md-menu-item>

        </md-menu-content>
      </md-menu>

    </md-menu-bar>

我现有的演示代码位于demo。

【问题讨论】:

你粘贴了完整的控制器代码吗? 实际上根据angular material doc,控制器上的那些代码与演示相关。但是这些对于使用角度材料菜单栏本身并不是必需的。我的意思是我们可以忽略演示中的那些过滤器、配置和控制器。 您最终找到解决方案了吗? 不,还没有运气。等待角材料修复它。 您应该在子菜单而不是父菜单上的 mouseenter 上停止事件传播。 【参考方案1】:

很简单,这里有一个答案,如果你使用bower安装angular-material,你需要:

    转到/bower-components/angular-material/modules/js文件夹 在任何测试编辑器(例如可视化代码、sublime 或 atom)中打开 menu.js 去找这行this.handleMenuItemHover = function(event)

然后使用我的修复:

this.handleMenuItemHover = function(event) 
if (self.isAlreadyOpening) return;
var nestedMenu = (
  event.target.querySelector('md-menu')
    || $mdUtil.getClosest(event.target, 'MD-MENU')
);
openMenuTimeout = $timeout(function() 
  if (nestedMenu) 
    nestedMenu = angular.element(nestedMenu).controller('mdMenu');
  
  if (self.currentlyOpenMenu && self.currentlyOpenMenu != nestedMenu)    
 
    var closeTo = self.nestLevel + 1;
    self.currentlyOpenMenu.close(true,  closeTo: closeTo );

    /******* david zhao: fix codes ******/
    if (!!nestedMenu) 
      self.isAlreadyOpening = true;
      nestedMenu.open();
    

   else if (nestedMenu && !nestedMenu.isOpen && nestedMenu.open) 
    self.isAlreadyOpening = true;
    nestedMenu.open();
  
, nestedMenu ? 100 : 250);
var focusableTarget = 
 event.currentTarget.querySelector('.md-button:not([disabled])');
focusableTarget && focusableTarget.focus();
;

【讨论】:

不接受修改源代码,因为每次更新包都会覆盖更改。【参考方案2】:

很遗憾,Google 并未修复 Angular Material 1 的许多问题,而是支持版本 2。 我认为这可能是鼓励人们切换到 Angular v2 的一种方式......

无论如何 - 我已经通过停止菜单项上的事件传播解决了悬停问题。然后将“鼠标离开”事件处理程序添加到子菜单容器,关闭当前菜单。

控制器 -

    $scope.noop = function(event)
        event.stopImmediatePropagation();
    ;

    $scope.closeSubMenu = function(event)
        mdMenu.hide();
    

查看 -

<md-menu-item ng-repeat="item in menu.items" >
    <md-menu-item>
        <md-menu>
            <md-button ng-click="$mdOpenMenu($event)" ng-mouseenter="noop($event)">item.title</md-button>
            <md-menu-content ng-mouseleave="closeSubMenu($event)" >
                <md-menu-item ng-repeat="subitem in item.items">
                    <md-button ng-click="$location.url(subitem.location)">subitem.title</md-button>
                </md-menu-item>
            </md-menu-content>
        </md-menu>
    </md-menu-item>
</md-menu-item>

【讨论】:

请注意,在您的控制器中,您是否应该通知$mdMenu 类似参数并将mdMenu.hide() 更改为$mdMenu.hide()

以上是关于鼠标悬停时打开角度材质菜单的主要内容,如果未能解决你的问题,请参考以下文章

如何在鼠标悬停时打开 react-bootstrap Dropdown?

jquery可拖动和鼠标悬停

Blazor 3.1 嵌套的鼠标悬停事件

在菜单组件中鼠标悬停时更改按钮的图标和文本颜色

Reactstrap 鼠标悬停时自动下拉菜单

Vuetify - 鼠标悬停时下拉菜单不突出显示