twitter-bootstrap mouseenter 上的 angular-bootstrap 下拉菜单,并在单击之前保持下拉菜单隐藏。
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27306866/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
angular-bootstrap dropdown on mouseenter and keep dropdown-menu from hiding before being clicked.
提问by Yahya KACEM
First, I'm aware of this posts:
Activating bootstrap dropdown menu on hover
Bootstrap Dropdown with Hover
How to make twitter bootstrap menu dropdown on hover rather than click
And others, but still not found the correct solution yet, here's what I did so far.
first I used the is-open attribute from the angular-bootstrap dropdown directive like this:
首先,我知道这篇文章:
Activating bootstrap dropdown menu on hover
Bootstrap Dropdown with Hover
How to make twitter bootstrap menu dropdown on hover 而不是点击
等等,但仍然没有找到正确的解决方案,这是我到目前为止所做的.
首先,我使用了 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>
that seemed to work but 2 bugs appeared:
这似乎有效,但出现了 2 个错误:
- the firstis when dropdown-toggle element is clicked the dropdown menu is gone clicking again wont bring it back you have to mouseleave then mouse enter the dropdown-tooggle to get the dropdown-menu back.
- the secondis a css/html problem.
- 第一个是单击下拉切换元素时,下拉菜单消失了,再次单击不会将其带回来,您必须鼠标离开,然后鼠标进入下拉切换以恢复下拉菜单。
- 第二个是 css/html 问题。
Usually the regular css solution for a dropdown is like this:
通常下拉列表的常规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>
Noticethe dropdown-menu now is inside the dropdown-toggle element which mean when moving with the mouse from the dropdown-toggle to the dropdown-menu it's moving from parent to child, so basically we still hovering over the dropdown-toggle since we are in it's child, which mean the dropdown-menu will still be visible, on other hand, the bootstrap dropdown works with the click event so having the dropdown-menu as a child of the dropdown-toggle is not needed, but now when someone wants to change the behavior to mouseenter/hover once the mouse leaves the dropdown-toggle the dropdown-menu disappear so we no longer have access to the dropdown-menu elements this is visible in this plunker
请注意,下拉菜单现在位于下拉切换元素内,这意味着当用鼠标从下拉切换到下拉菜单时,它正在从父项移动到子项,所以基本上我们仍然悬停在下拉切换上,因为我们是在它的子项中,这意味着下拉菜单仍然可见,另一方面,引导下拉菜单与单击事件一起使用,因此不需要将下拉菜单作为下拉切换的子项,但是现在当有人想要时一旦鼠标离开下拉菜单,将行为更改为鼠标输入/悬停 - 切换下拉菜单消失,因此我们不再可以访问在此plunker 中可见的下拉菜单元素
To fix the first bug, I just removed the dropdown directive then replaced the is-open with ng-class directive like this.
Change this:
为了修复第一个错误,我只是删除了下拉指令,然后像这样用 ng-class 指令替换了 is-open。
改变这个:
<span class="dropdown" dropdown is-open="status.isopen">
to this:
对此:
<span class="dropdown" ng-class="{'open': status.isopen}">
The rest stays the same plunkerthat fixed the first bug.
The second bug is tricky, since the dropdown-menu is no longer a child of the dropdown-toggle the hover effect wont last while moving from the toggle to the menu, so I did this.
Changed this:
其余的保持与修复第一个错误相同的plunker。
第二个错误很棘手,因为下拉菜单不再是下拉切换的子项,所以在从切换切换到菜单时悬停效果不会持续,所以我这样做了。改变了这一点:
<ul class="dropdown-menu">
to this:
对此:
<ul
class="dropdown-menu"
ng-mouseenter="status.isopen = true"
ng-mouseleave="status.isopen = false"
>
That did it but another bug appeared when clicking the dropdown-menu item it stays open, so I kept hacking by doing this. changed this:
这样做了,但是在单击它保持打开状态的下拉菜单项时出现了另一个错误,所以我继续通过这样做来进行黑客攻击。改变了这一点:
<li ng-repeat="choice in items">
to this:
对此:
<li ng-repeat="choice in items" ng-click="status.isopen = false">
That give me the required behavior plunker.
That said, this is not a good solution since a lot of directives are involved here for a simple visual effect, the last plunker I provided contains a css solution with no Bootstrap or AngularJS involved, though it is the required behavior it is not the required html structure or visual result, what I need is to have a space between the dropdown-toggle and the dropdown-menu not a padding of the toggle element just an empty space, which make the css solution not valid in this situation.
So, my question is there a better way of doing this without adding a new plugin/library more clean and easily reusable solution for the hover drop down menu?
这给了我所需的行为plunker。
也就是说,这不是一个好的解决方案,因为这里涉及很多指令以获得简单的视觉效果,我提供的最后一个 plunker 包含一个不涉及 Bootstrap 或 AngularJS 的 css 解决方案,尽管这是必需的行为,但不是必需的html 结构或视觉结果,我需要的是在下拉切换和下拉菜单之间有一个空格,而不是切换元素的填充只是一个空白空间,这使得 css 解决方案在这种情况下无效。
所以,我的问题是有没有更好的方法来做到这一点,而无需为悬停下拉菜单添加新的插件/库更干净且易于重用的解决方案?
回答by Kenny Ki
First, have the toggling on the top-most parent element(in this case, the <span>)
首先,在最顶层的父元素上进行切换(在本例中为<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>
This will allow the behavior you wanted - while still allowing clicking to show/hide the menu ;-)
这将允许您想要的行为-同时仍然允许单击以显示/隐藏菜单;-)
However there's an annoyance: if you move the mouse cursor slower and pass the small gap between the toggle and menu, it will hide the menu.
但是有一个烦恼:如果您移动鼠标光标的速度较慢并通过切换和菜单之间的小间隙,它将隐藏菜单。
So secondly, add a small CSS to remove the gap
那么其次,增加一个小的CSS删除差距
.dropdown-menu {
margin-top: 0;
}
See the action in this plunker.
请参阅此plunker 中的操作。
回答by Nick
Try adding this line to your css:
尝试将此行添加到您的 css:
.btn-group:hover>.dropdown-menu { display: block; margin-top: 0; }
You'll have to remove your is-open, ng-mouseenter and ng-mouseleave directives.
您必须删除 is-open、ng-mouseenter 和 ng-mouseleave 指令。
回答by zoom
Below is the solution I came up with, while working on the same issue.
以下是我在处理同一问题时提出的解决方案。
I used a simple custom directive that:
我使用了一个简单的自定义指令:
- binds the
mouseenterandmouseleaveevents to the dropdown in order correctly to show/hide the menu. - dynamically adds a custom CSS class to the dropdown menu in order to prevent the menu from disappearing when moving the cursor from the button to the menu. Note that this solution has the advantage of not removing the visual gap between the button and menu.
- prevents the menu from disappearing when the button is clicked.
- 将
mouseenter和mouseleave事件绑定到下拉菜单,以便正确显示/隐藏菜单。 - 动态添加自定义 CSS 类到下拉菜单,以防止将光标从按钮移动到菜单时菜单消失。请注意,此解决方案的优点是不会消除按钮和菜单之间的视觉间隙。
- 防止单击按钮时菜单消失。
The CSS rule uses a beforepseudo-element to fill the gap between the button and the menu. I added the borderproperty which can be uncommented to easily get a visual feedback.
CSS 规则使用before伪元素来填充按钮和菜单之间的空隙。我添加了border可以取消注释的属性,以便轻松获得视觉反馈。
.dropdown-hover-menu::before {
content: '';
position: absolute;
left: 0;
width: 100%;
top: -3px;
height: 3px;
/*border: 1px solid black;*/
}
The HTML structure of the snippet is based on the available examples in the dropdown section of the angular-ui bootstrap documentation
代码段的 HTML 结构基于angular-ui bootstrap 文档下拉部分中的可用示例
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>
回答by falsarella
I know you want a solution without adding a new plugin/library, but you (or others seeking for this behavior) might want to try using No Close from Dropdown Enhancements libto keep the dropdown open even after clicking in one of its options:
我知道您想要一个解决方案without adding a new plugin/library,但您(或其他寻求这种行为的人)可能想尝试使用“下拉增强”库中的“不关闭”来保持下拉菜单打开,即使在单击其中一个选项后:
Do not close the menu on click on radio add class
.noclose.
不要在单击 radio add class 时关闭菜单
.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>
Also add a CSS solution for the hovering problem:
还要为悬停问题添加一个 CSS 解决方案:
.btn-group:hover .dropdown-menu.noclose {
display: block;
}
.dropdown-menu.noclose {
margin-top: 0px;
}
And, of course, don't forget to import the libs:
而且,当然,不要忘记导入库:
<script src="./js/dropdowns-enhancement.min.js"></script><link href="./css/dropdowns-enhancement.css" rel="stylesheet"\>
<script src="./js/dropdowns-enhancement.min.js"></script><link href="./css/dropdowns-enhancement.css" rel="stylesheet"\>
In your case I suggest you to study the Dropdown Enhancements's source codeto see how it works and maybe find a more suitable solution.
在你的情况下,我建议你研究Dropdown Enhancements 的源代码,看看它是如何工作的,也许会找到更合适的解决方案。

