mouseenter 上的 angular-bootstrap 下拉菜单,并在单击之前保持下拉菜单隐藏。
Posted
技术标签:
【中文标题】mouseenter 上的 angular-bootstrap 下拉菜单,并在单击之前保持下拉菜单隐藏。【英文标题】:angular-bootstrap dropdown on mouseenter and keep dropdown-menu from hiding before being clicked. 【发布时间】:2015-02-03 02:10:24 【问题描述】:首先,我知道这个帖子:Activating bootstrap dropdown menu on hoverBootstrap Dropdown with HoverHow to make twitter bootstrap menu dropdown on hover rather than click 还有其他人,但仍未找到正确的解决方案,这是我到目前为止所做的。 首先,我使用了 angular-bootstrap 下拉指令中的 is-open 属性,如下所示:
<span class="dropdown" dropdown is-open="status.isopen">
<a
href
class="dropdown-toggle"
ng-mouseenter="status.isopen = true"
ng-mouseleave="status.isopen = false"
>
hover me for a dropdown with angular-bootstrap
</a>
<ul
class="dropdown-menu"
>
<li ng-repeat="choice in items">
<a href>choice</a>
</li>
</ul>
</span>
这似乎可行,但出现了 2 个错误:
第一个是当点击下拉切换元素时,下拉菜单消失了,再次点击不会把它带回来你必须鼠标离开,然后鼠标进入下拉切换以恢复下拉菜单。 第二个是css/html问题。通常下拉菜单的常规 css 解决方案是这样的:
<a class="css-dropdown">
hover here with css.
<div class="css-dropdown-menu">
<p>item 1</p>
<p>item 2</p>
<p>item 3</p>
</div>
</a>
注意下拉菜单现在位于下拉切换元素内,这意味着当用鼠标从下拉切换到下拉菜单时,它会从父级移动到子级,所以基本上我们仍然悬停在下拉开关上,因为我们是它的孩子,这意味着下拉菜单仍然可见,另一方面,引导下拉菜单与点击事件一起使用,因此将下拉菜单作为下拉菜单的孩子-不需要切换,但是现在当有人想在鼠标离开下拉菜单时将行为更改为鼠标输入/悬停时,下拉菜单会消失,因此我们不再可以访问下拉菜单元素,这在 @987654324 中可见@
为了修复第一个错误,我刚刚删除了下拉指令,然后将 is-open 替换为 ng-class 指令,如下所示。 改变这个:
<span class="dropdown" dropdown is-open="status.isopen">
到这里:
<span class="dropdown" ng-class="'open': status.isopen">
其余部分与修复第一个错误的plunker 保持一致。 第二个错误很棘手,因为下拉菜单不再是下拉切换的子项,从切换到菜单时悬停效果不会持续,所以我这样做了。 改变了这个:
<ul class="dropdown-menu">
到这里:
<ul
class="dropdown-menu"
ng-mouseenter="status.isopen = true"
ng-mouseleave="status.isopen = false"
>
做到了,但是在单击下拉菜单项时出现了另一个错误,它保持打开状态,所以我一直这样做。 改变了这个:
<li ng-repeat="choice in items">
到这里:
<li ng-repeat="choice in items" ng-click="status.isopen = false">
这给了我所需的行为plunker。 也就是说,这不是一个好的解决方案,因为这里涉及很多指令以获得简单的视觉效果,我提供的最后一个 plunker 包含一个不涉及 Bootstrap 或 AngularJS 的 css 解决方案,尽管它是必需的行为,但不是必需的html 结构或视觉结果,我需要的是在下拉切换和下拉菜单之间有一个空格,而不是切换元素的填充只是一个空白,这使得 css 解决方案在这种情况下无效。 那么,我的问题是否有更好的方法来做到这一点,而无需为悬停下拉菜单添加新的插件/库更干净且易于重用的解决方案?
【问题讨论】:
您解决了这个问题吗?还是它仍然开放,我认为现在应该关闭:) 不,我没有在这方面工作,但我有太多其他的东西,它仍然使用我在这里提到的相同的 hack :(,如果你有一个更好的解决方案清洁器和更少的指令,我接受建议。 让我查一下,我会回复你的 您好,除了上面提到的以外,您还有什么好的解决方案 @AvinashSolanki,没有。 【参考方案1】:首先,切换最顶层的父元素(在本例中为<span>
)
<span class="btn-group" dropdown is-open="status.isopen" ng-mouseenter="status.isopen = true" ng-mouseleave="status.isopen = false">
<a class="btn btn-primary dropdown-toggle" dropdown-toggle>
Button dropdown <span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</span>
这将允许你想要的行为 - 同时仍然允许点击显示/隐藏菜单;-)
但是有一个烦恼:如果您将鼠标光标移动得较慢并通过切换和菜单之间的小间隙,它将隐藏菜单。
所以其次,添加一个小的CSS来消除差距
.dropdown-menu
margin-top: 0;
查看此plunker 中的操作。
【讨论】:
【参考方案2】:我知道你想要一个解决方案 without adding a new plugin/library
,但你(或其他寻求这种行为的人)可能想尝试使用 No Close from Dropdown Enhancements lib 来保持下拉菜单打开,即使在点击其中一个选项:
不要在点击收音机添加类
.noclose
时关闭菜单。
<div class="btn-group">
<button data-toggle="dropdown" class="btn btn-default dropdown-toggle">
Checked option <span class="caret"></span>
</button>
<ul class="dropdown-menu noclose">
<li>
<input type="radio" id="gr1_1" name="gr1" value="1">
<label for="gr1_1">Option 1</label>
</li>
<li>
<input type="radio" id="gr1_2" name="gr1" value="2">
<label for="gr1_2">Option 2</label>
</li>
<li>
<input type="radio" id="gr1_3" name="gr1" value="3">
<label for="gr1_3">Option 3</label>
</li>
</ul>
</div>
还为悬停问题添加 CSS 解决方案:
.btn-group:hover .dropdown-menu.noclose
display: block;
.dropdown-menu.noclose
margin-top: 0px;
当然,不要忘记导入库:
<script src="./js/dropdowns-enhancement.min.js"></script>
<link href="./css/dropdowns-enhancement.css" rel="stylesheet"\>
对于你的情况,我建议你研究一下Dropdown Enhancements's source code,看看它是如何工作的,也许会找到更合适的解决方案。
【讨论】:
【参考方案3】:尝试将此行添加到您的 css:
.btn-group:hover>.dropdown-menu display: block; margin-top: 0;
您必须删除您的 is-open、ng-mouseenter 和 ng-mouseleave 指令。
【讨论】:
【参考方案4】:以下是我在处理同一问题时提出的解决方案。
我使用了一个简单的自定义指令:
将mouseenter
和mouseleave
事件绑定到下拉菜单,以便正确显示/隐藏菜单。
为下拉菜单动态添加自定义 CSS 类,以防止将光标从按钮移动到菜单时菜单消失。 请注意,此解决方案的优点是不会消除按钮和菜单之间的视觉差距。
防止单击按钮时菜单消失。
CSS 规则使用before
伪元素来填充按钮和菜单之间的空隙。我添加了 border
属性,可以取消注释以轻松获得视觉反馈。
.dropdown-hover-menu::before
content: '';
position: absolute;
left: 0;
width: 100%;
top: -3px;
height: 3px;
/*border: 1px solid black;*/
sn-p 的 HTML 结构基于 dropdown section of the angular-ui bootstrap documentation 中的可用示例
angular.module('app', ['ui.bootstrap'])
.directive('dropdownHover', function()
return
require: 'uibDropdown',
link: function(scope, element, attrs, dropdownCtrl)
var menu = angular.element(element[0].querySelector('.dropdown-menu')),
button = angular.element(element[0].querySelector('.dropdown-toggle'));
menu.addClass('dropdown-hover-menu');
element.bind('mouseenter', onMouseenter);
element.bind('mouseleave', onMouseleave);
button.bind('click', onClick);
function openDropdown(open)
scope.$apply(function()
dropdownCtrl.toggle(open);
);
function onMouseenter(event)
if (!element.hasClass('disabled') && !attrs.disabled)
openDropdown(true);
;
function onMouseleave(event)
openDropdown(false);
;
function onClick(event)
event.stopPropagation();
scope.$on('$destroy', function()
element.unbind('mouseenter', onMouseenter);
element.unbind('mouseleave', onMouseleave);
button.unbind('click', onClick);
);
;
);
.dropdown-hover-menu::before
content: '';
position: absolute;
left: 0;
width: 100%;
top: -3px;
height: 3px;
/*border: 1px solid black;*/
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.3/ui-bootstrap-tpls.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app="app">
<div class="btn-group" uib-dropdown dropdown-hover>
<button type="button" class="btn btn-primary dropdown-toggle">
Button dropdown <span class="caret"></span>
</button>
<ul class="dropdown-menu" uib-dropdown-menu role="menu">
<li role="menuitem"><a href="#">Action</a>
</li>
<li role="menuitem"><a href="#">Another action</a>
</li>
<li role="menuitem"><a href="#">Something else here</a>
</li>
<li class="divider"></li>
<li role="menuitem"><a href="#">Separated link</a>
</li>
</ul>
</div>
</div>
【讨论】:
以上是关于mouseenter 上的 angular-bootstrap 下拉菜单,并在单击之前保持下拉菜单隐藏。的主要内容,如果未能解决你的问题,请参考以下文章
当光标隐藏在其他 HTML 元素后面时如何触发 mouseenter 事件?