Как сделать так, чтобы всплывающее меню Twitter Bootstrap при наведении курсора, а не при нажатии - PullRequest
1122 голосов
/ 16 января 2012

Я бы хотел, чтобы меню Bootstrap автоматически выпадало при наведении курсора, а не щелкало заголовок меню. Я также хотел бы потерять маленькие стрелки рядом с заголовками меню.

Ответы [ 41 ]

10 голосов
/ 17 августа 2012

Еще лучше с jQuery:

jQuery('ul.nav li.dropdown').hover(function() {
  jQuery(this).find('.dropdown-menu').stop(true, true).show();
  jQuery(this).addClass('open');
}, function() {
  jQuery(this).find('.dropdown-menu').stop(true, true).hide();
  jQuery(this).removeClass('open');
});
9 голосов
/ 23 сентября 2015

Вы можете использовать метод $().dropdown('toggle') по умолчанию для переключения выпадающего меню при наведении курсора:

$(".nav .dropdown").hover(function() {
  $(this).find(".dropdown-toggle").dropdown("toggle");
});
8 голосов
/ 01 ноября 2012

Просто хочу добавить, что если у вас несколько раскрывающихся списков (как у меня), вы должны написать:

ul.nav li.dropdown:hover > ul.dropdown-menu {
    display: block;    
}

И все будет работать правильно.

8 голосов
/ 01 марта 2014

Лучший способ сделать это - просто вызвать событие нажатия Bootstrap при наведении курсора. Таким образом, он все равно должен оставаться дружественным к сенсорному устройству.

$('.dropdown').hover(function(){ 
  $('.dropdown-toggle', this).trigger('click'); 
});
7 голосов
/ 30 сентября 2013

Мне удалось это следующим образом:

$('ul.nav li.dropdown').hover(function(){
       $(this).children('ul.dropdown-menu').slideDown(); 
    }, function(){
       $(this).children('ul.dropdown-menu').slideUp(); 
});

Надеюсь, это кому-нибудь поможет ...

7 голосов
/ 10 сентября 2013

На мой взгляд, лучший способ таков:

;(function($, window, undefined) {
    // Outside the scope of the jQuery plugin to
    // keep track of all dropdowns
    var $allDropdowns = $();

    // If instantlyCloseOthers is true, then it will instantly
    // shut other nav items when a new one is hovered over
    $.fn.dropdownHover = function(options) {

        // The element we really care about
        // is the dropdown-toggle's parent
        $allDropdowns = $allDropdowns.add(this.parent());

        return this.each(function() {
            var $this = $(this),
                $parent = $this.parent(),
                defaults = {
                    delay: 500,
                    instantlyCloseOthers: true
                },
                data = {
                    delay: $(this).data('delay'),
                    instantlyCloseOthers: $(this).data('close-others')
                },
                settings = $.extend(true, {}, defaults, options, data),
                timeout;

            $parent.hover(function(event) {

                // So a neighbor can't open the dropdown
                if(!$parent.hasClass('open') && !$this.is(event.target)) {
                    return true;
                }

                if(settings.instantlyCloseOthers === true)
                    $allDropdowns.removeClass('open');

                window.clearTimeout(timeout);
                $parent.addClass('open');
            }, function() {
                timeout = window.setTimeout(function() {
                    $parent.removeClass('open');
                }, settings.delay);
            });

            // This helps with button groups!
            $this.hover(function() {
                if(settings.instantlyCloseOthers === true)
                    $allDropdowns.removeClass('open');

                window.clearTimeout(timeout);
                $parent.addClass('open');
            });

            // Handle submenus
            $parent.find('.dropdown-submenu').each(function(){
                var $this = $(this);
                var subTimeout;
                $this.hover(function() {
                    window.clearTimeout(subTimeout);
                    $this.children('.dropdown-menu').show();

                    // Always close submenu siblings instantly
                    $this.siblings().children('.dropdown-menu').hide();
                }, function() {
                    var $submenu = $this.children('.dropdown-menu');
                    subTimeout = window.setTimeout(function() {
                        $submenu.hide();
                    }, settings.delay);
                });
            });
        });
    };

    $(document).ready(function() {
        // apply dropdownHover to all elements with the data-hover="dropdown" attribute
        $('[data-hover="dropdown"]').dropdownHover();
    });
})(jQuery, this);

Пример разметки:

<li class="dropdown">
    <a href="#" class="dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" data-delay="1000" data-close-others="false">
        Account <b class="caret"></b>
    </a>
    <ul class="dropdown-menu">
        <li><a tabindex="-1" href="#">My Account</a></li>
        <li class="divider"></li>
        <li><a tabindex="-1" href="#">Change Email</a></li>
        <li><a tabindex="-1" href="#">Change Password</a></li>
        <li class="divider"></li>
        <li><a tabindex="-1" href="#">Logout</a></li>
    </ul>
</li>
5 голосов
/ 27 февраля 2012

Это, вероятно, глупая идея, но просто убрав стрелку, указывающую вниз, вы можете удалить

<b class="caret"></b>

Это ничего не значит для направленной вверх, хотя ...

5 голосов
/ 14 мая 2014

Также добавлен margin-top: 0 для сброса поля начальной загрузки css для .dropdown-menu, чтобы список меню не исчезал, когда пользователь медленно перемещается из выпадающего меню в список меню.

ul.nav li.dropdown:hover > ul.dropdown-menu {
    display: block;    
}

.nav .dropdown-menu {
    margin-top: 0;
}
5 голосов
/ 27 июня 2015

Я опубликовал правильный плагин для функции всплывающей подсказки Bootstrap 3, в котором вы даже можете определить, что происходит при нажатии на элемент dropdown-toggle (щелчок можно отключить):

https://github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover


Почему я сделал это, когда уже есть много решений?

У меня были проблемы со всеми ранее существующими решениями. Простые CSS не используют класс .open в .dropdown, поэтому при раскрытии раскрывающегося элемента не будет никакой обратной связи.

js мешают нажатию на .dropdown-toggle, поэтому раскрывающийся список отображается при наведении курсора, а затем скрывается при нажатии на раскрывающемся раскрывающемся меню, а при перемещении мыши запускается раскрывающийся список, который снова появляется , Некоторые из решений js нарушают совместимость с iOS, некоторые плагины не работают в современных настольных браузерах, поддерживающих сенсорные события.

Именно поэтому я создал Bootstrap Dropdown Hover плагин , который предотвращает все эти проблемы с помощью , используя только стандартный API-интерфейс Bootstrap javascript, без какого-либо взлома . Даже атрибуты Aria отлично работают с этим плагином.

4 голосов
/ 26 октября 2016

Используйте этот код для открытия подменю при наведении курсора мыши (только на рабочем столе):

$('ul.nav li.dropdown').hover(function () {
    if ($(window).width() > 767) {
        $(this).find('.dropdown-menu').show();
    }
}, function () {
    if ($(window).width() > 767) {
        $(this).find('.dropdown-menu').hide().css('display','');
    }
});

И если вы хотите, чтобы меню первого уровня было интерактивным, даже на мобильном устройстве, добавьте:

    $('.dropdown-toggle').click(function() {
    if ($(this).next('.dropdown-menu').is(':visible')) {
        window.location = $(this).attr('href');
    }
});

Подменю (раскрывающееся меню) открывается при наведении курсора мыши на рабочем столе и при нажатии / прикосновении на мобильном телефоне и планшете. После открытия подменю второй щелчок откроет ссылку. Благодаря if ($(window).width() > 767) подменю займет всю ширину экрана на мобильном телефоне.

...