W3C объясняет разбор в форме псевдорежима: W3C Link
Следуйте за ссылками на QName
, S
и Attribute
, чтобы получить более четкое картина. Исходя из этого, вы можете создать довольно хорошее регулярное выражение для обработки таких вещей, как снятие тегов.
Простое решение только для CSS:
.dropdown:hover>.dropdown-menu {
display: block;
}
При нажатии кнопки он все равно будет переключать на него класс show
(и останется открытым, когда больше не будет вибрировать).
Чтобы обойти это правильно , следует использовать события и свойства, зарезервированные для устройств на основе указателей: jQuery mouseenter
, mouseleave
и :hover
. Должно работать гладко, интуитивно, хотя и не мешать вообще тем, как выпадающее меню работает на сенсорных устройствах. Попробуйте, дайте мне знать, если это сработает для вас:
Complete, jQuery + CSS solution ( touch нетронутый):
$('body').on('mouseenter mouseleave','.dropdown',function(e){
var _d=$(e.target).closest('.dropdown');_d.addClass('show');
setTimeout(function(){
_d[_d.is(':hover')?'addClass':'removeClass']('show');
$('[data-toggle="dropdown"]', _d).attr('aria-expanded',_d.is(':hover'));
},300);
});
.dropdown:hover>.dropdown-menu {
display: block;
}
$('body').on('mouseenter mouseleave','.dropdown',function(e){
var _d=$(e.target).closest('.dropdown');
_d.addClass('show');
setTimeout(function(){
_d[_d.is(':hover')?'addClass':'removeClass']('show');
$('[data-toggle="dropdown"]', _d).attr('aria-expanded',_d.is(':hover'));
},300);
});
.dropdown:hover>.dropdown-menu {
display: block;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">Navbar</a>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="http://example.com" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown link
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
</div>
</nav>
Я уже использовал и создал навигационную панель, когда мне было предложено изменить ее на зависающее взаимодействие, поэтому в итоге это было как исправление с использованием jQuery.
function bootstrapHoverMenu (bp = 768) {
// close all dropdowns that are open
$('body').click( function (e) {
$('.dropdown-menu.show').removeClass('show');
});
// show dropdown for the link clicked
$('.nav-item').hover(function (e) {
$('.dropdown-menu.show').removeClass('show');
if(( $(window).width() >= bp )) {
$dd = $(this).find('.dropdown-menu');
$dd.addClass('show');
}
});
// get href for top level link if clicked and open
$('.dropdown').click(function (e) {
if( $(window).width() < bp ) {
$('.dropdown-menu').css({'display': 'none'});
}
$href = $(this).find('.nav-link').attr('href');
window.open($href, '_self');
});
}
$(document).ready( function() {
// when page ready run the fix
bootstrapHoverMenu();
});
Даунсайд только для мобильных устройств ссылки верхнего уровня.
Просто добавьте этот простой код css в ваш стиль и вы готовы к работе.
.dropdown:hover > .dropdown-menu {
display: block;
}
.dropdown > .dropdown-toggle:active {
/*Without this, clicking will make it sticky*/
pointer-events: none;
}
Я думаю, что это просто работает с bootstrap 4, я добавляю inline, но вы всегда можете связать событие с скриптом.
<a
onmouseover="$('#navbarDropdownMenuLink').dropdown('toggle')"
class="nav-link dropdown-toggle"
href="http://example.com"
id="navbarDropdownMenuLink"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false">
Dropdown link
</a>
«полное» решение jQuery + CSS от Andrei имеет правильное намерение, но оно многословное и все еще неполное. Неполный, потому что он пропускает несколько других изменений, которые должны произойти, и многословный, поскольку Bootstrap уже предоставляет метод dropdown () , который мы можем использовать вместо этого.
Итак, это решение - просто jQuery; CSS не требуется:
$('body').on('mouseover mouseout', '[data-toggle=dropdown]', function (e) {
$(e.target).dropdown('toggle');
});
toggle
s на событиях мыши. Если он только пропустит один раз, раскрывающийся список останется открытым, когда он не зависнет и не скроется при зависании. Обычно можно пропустить последовательность указателей ввода / вывода, наметывая курсор над элементом. Но для правильного тестирования наведите элемент, измените вкладку или окно и вернитесь в окно с помощью мыши в другой позиции. Теперь наведите элемент на элемент.
– Andrei Gheorghiu
9 July 2018 в 14:44
mouseover mouseout
, похоже, исправляет эту проблему. Спасибо, я отредактирую свой пост.
– Lionel Wong
21 July 2018 в 05:54
Функциональность Bootstrap, похоже, немного изменилась с момента выпуска v4. Элемент .dropdown-menu
также появляется в дополнение к .dropdown
классу .show
. Я адаптировал ответ Андрея, чтобы переключить класс на .dropdown-menu
. Обратите внимание, что CSS больше не нужен, и HTML тот же, за исключением того, что я обновил ссылки на текущие версии, а класс nav изменился на navbar-expand-md
.
$('body').on('mouseenter mouseleave', '.dropdown', function (e) {
var dropdown = $(e.target).closest('.dropdown');
var menu = $('.dropdown-menu', dropdown);
dropdown.addClass('show');
menu.addClass('show');
setTimeout(function () {
dropdown[dropdown.is(':hover') ? 'addClass' : 'removeClass']('show');
menu[dropdown.is(':hover') ? 'addClass' : 'removeClass']('show');
}, 300);
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<nav class="navbar navbar-expand-md navbar-light bg-faded">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">Navbar</a>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="http://example.com" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown link
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
</div>
</nav>
<div style="width: 100%; overflow: scroll;"><table class="table table-striped table-bordered" style="font-size:12px">
. Это гарантирует, что вы все равно сможете следить за кликами на уровне верхнего уровня и совместимы с мобильными устройствами.
blockquote>Это было сделано с учетом настольных компьютеров и мобильных устройств. Попал в оболочку jQuery с условием, который проверяет, превышает ли ширина окна 768px.
jQuery
/** Dropdown on hover */ $(".nav-link.dropdown-toggle").hover( function () { // Open up the dropdown $(this).removeAttr('data-toggle'); // remove the data-toggle attribute so we can click and follow link $(this).parent().addClass('show'); // add the class show to the li parent $(this).next().addClass('show'); // add the class show to the dropdown div sibling }, function () { // on mouseout check to see if hovering over the dropdown or the link still var isDropdownHovered = $(this).next().filter(":hover").length; // check the dropdown for hover - returns true of false var isThisHovered = $(this).filter(":hover").length; // check the top level item for hover if(isDropdownHovered || isThisHovered) { // still hovering over the link or the dropdown } else { // no longer hovering over either - lets remove the 'show' classes $(this).attr('data-toggle', 'dropdown'); // put back the data-toggle attr $(this).parent().removeClass('show'); $(this).next().removeClass('show'); } }); // Check the dropdown on hover $(".dropdown-menu").hover( function () { }, function() { var isDropdownHovered = $(this).prev().filter(":hover").length; // check the dropdown for hover - returns true of false var isThisHovered= $(this).filter(":hover").length; // check the top level item for hover if(isDropdownHovered || isThisHovered) { // do nothing - hovering over the dropdown of the top level link } else { // get rid of the classes showing it $(this).parent().removeClass('show'); $(this).removeClass('show'); } });
CSS
@media(min-width: 768px) { .dropdown-menu { margin-top: 0; // fixes closing on slow mouse transition } }
Это решение включается и выключается
<script>
$(document).ready(function() {
// close all dropdowns that are open
$('body').click(function(e) {
$('.nav-item.show').removeClass('show');
//$('.nav-item.clicked').removeClass('clicked');
$('.dropdown-menu.show').removeClass('show');
});
$('.nav-item').click( function(e) {
$(this).addClass('clicked')
});
// show dropdown for the link clicked
$('.nav-item').hover(function(e) {
if ($('.nav-item.show').length < 1) {
$('.nav-item.clicked').removeClass('clicked');
}
if ($('.nav-item.clicked').length < 1) {
$('.nav-item.show').removeClass('show');
$('.dropdown-menu.show').removeClass('show');
$dd = $(this).find('.dropdown-menu');
$dd.parent().addClass('show');
$dd.addClass('show');
}
});
});</script>
Чтобы отключить зависание для меню уменьшения размера lg, добавьте
if(( $(window).width() >= 992 )) {
split button
. Они сделаны именно для этого. – Andrei Gheorghiu 12 February 2017 в 20:27