css - style - bootstrap3 dropdown




如何在懸停而不是點擊的情況下製作Twitter Bootstrap菜單下拉菜單 (20)

jQuery解決方案很好,但它需要處理點擊事件(針對移動設備或平板電腦),因為懸停無法正常工作......可能可能會進行一些窗口重新尺寸檢測?

Andres Ilich的答案似乎運作良好,但它應該包裝在媒體查詢中:

@media (min-width: 980px) {

    .dropdown-menu .sub-menu {
        left: 100%;
        position: absolute;
        top: 0;
        visibility: hidden;
        margin-top: -1px;
    }

    .dropdown-menu li:hover .sub-menu {
        visibility: visible;
    }

    .dropdown:hover .dropdown-menu {
        display: block;
    }

    .nav-tabs .dropdown-menu, .nav-pills .dropdown-menu, .navbar .dropdown-menu {
        margin-top: 0;
    }

    .navbar .sub-menu:before {
        border-bottom: 7px solid transparent;
        border-left: none;
        border-right: 7px solid rgba(0, 0, 0, 0.2);
        border-top: 7px solid transparent;
        left: -7px;
        top: 10px;
    }
    .navbar .sub-menu:after {
        border-top: 6px solid transparent;
        border-left: none;
        border-right: 6px solid #fff;
        border-bottom: 6px solid transparent;
        left: 10px;
        top: 11px;
        left: -6px;
    }
}

我希望我的Bootstrap菜單在懸停時自動下拉,而不必單擊菜單標題。 我也想失去菜單標題旁邊的小箭頭。


[更新]插件在GitHub ,我正在做一些改進(比如只用於數據屬性(不需要JS)。我已經在下面留下了代碼,但它與GitHub上的不一樣。

我喜歡純粹的CSS版本,但在關閉之前有一段延遲是很好的,因為它通常是一種更好的用戶體驗(即,不會因為在下拉菜單之外出現1 px的鼠標滑移而受到懲罰),並且如評論中所述,那麼您需要處理1px的保證金,或者有時在導入原始按鈕的下拉菜單時導航會意外關閉,等等。

我創建了一個在幾個網站上使用的快速插件,它的工作很好。 每個導航項目都是獨立處理的,所以他們有自己的延遲計時器等。

JS

// 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(),
            defaults = {
                delay: 500,
                instantlyCloseOthers: true
            },
            data = {
                delay: $(this).data('delay'),
                instantlyCloseOthers: $(this).data('close-others')
            },
            options = $.extend(true, {}, defaults, options, data),
            timeout;

        $this.hover(function() {
            if(options.instantlyCloseOthers === true)
                $allDropdowns.removeClass('open');

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

delay參數非常明顯, instantlyCloseOthers會立即關閉所有其他下拉菜單,當您將鼠標懸停在新的下拉菜單上時,這些下拉菜單會打開。

不是純粹的CSS,但希望能在這麼晚的時候幫助其他人(例如,這是一個舊線程)。

如果你願意的話,你可以看到我經歷的不同過程(在#concrete5 IRC的討論中),通過這個要點的不同步驟來實現它: https://gist.github.com/3876924https://gist.github.com/3876924

插件模式方法更加清晰,以支持個人計時器等。

查看博客文章了解更多信息。


使用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');
});

使用此代碼打開mousehover上的子菜單(僅限桌面):

$('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) ,子菜單將在移動設備上顯示全屏寬度。


只是想補充一點,如果你有多個下拉菜單(和我一樣),你應該寫:

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

它會正常工作。


只需三行代碼即可自定義您的CSS樣式

.dropdown:hover .dropdown-menu {
   display: block;
}

在我看來,最好的方法是這樣的:

;(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>

如果你有一個像這樣的dropdown類的元素(例如):

<ul class="list-unstyled list-inline">
    <li class="dropdown">
        <a data-toggle="dropdown" href="#"><i class="fa fa-bars"></i> Dropdown 1</a>
        <ul class="dropdown-menu">
            <li><a href="">Item 1</a></li>
            <li><a href="">Item 2</a></li>
            <li><a href="">Item 3</a></li>
            <li><a href="">Item 4</a></li>
            <li><a href="">Item 5</a></li>
        </ul>
    </li>
    <li class="dropdown">
        <a data-toggle="dropdown" href="#"><i class="fa fa-user"></i> Dropdown 2</a>
        <ul class="dropdown-menu">
            <li><a href="">Item A</a></li>
            <li><a href="">Item B</a></li>
            <li><a href="">Item C</a></li>
            <li><a href="">Item D</a></li>
            <li><a href="">Item E</a></li>
        </ul>
    </li>
</ul>

然後,您可以使用以下代碼片段的jQuery代碼,將鼠標懸停在下拉菜單上,而不必點擊標題:

<script>
    $('.dropdown').hover(
        function() {
            $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn();
        },
        function() {
            $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut();
        }
    );

    $('.dropdown-menu').hover(
        function() {
            $(this).stop(true, true);
        },
        function() {
            $(this).stop(true, true).delay(200).fadeOut();
        }
    );
</script>

這裡是一個演示

這個答案依賴@邁克爾答案 ,我做了一些改變,並添加了一些添加到下拉菜單正常工作


您可以使用默認的$().dropdown('toggle')方法切換懸停時的下拉菜單:

$(".nav .dropdown").hover(function() {
  $(this).find(".dropdown-toggle").dropdown("toggle");
});

我使用了一些jQuery:

// Add hover effect to menus
jQuery('ul.nav li.dropdown').hover(function() {
  jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn();
}, function() {
  jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut();
});

我已經發布了Bootstrap 3下拉懸停功能的正確插件 ,您甚至可以在單擊dropdown-toggle元素(可以禁用點擊)時定義會發生什麼情況:

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

為什麼我在已經有很多解決方案的情況下做到了?

我遇到了以前所有現有解決方案的問題。 簡單的CSS不會在.open使用.open類,因此當下拉菜單可見時,下拉切換元素將不會有任何反饋。

js的人正在干擾點擊.dropdown-toggle ,所以下拉菜單顯示在懸停狀態,然後點擊打開的下拉菜單時隱藏下拉菜單,移出鼠標將觸發下拉菜單再次顯示。 一些js解決方案打破了iOS的兼容性,一些插件無法在支持觸摸事件的現代桌面瀏覽器上運行。

這就是為什麼我製作了github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover 插件 ,它可以通過僅使用標準Bootstrap JavaScript API來防止所有這些問題,而無需任何破解 。 即使是詠嘆調屬性也適用於這個插件。


我已經管理它如下:

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

我希望這可以幫助別人...


為了增強Sudharshan的回答 ,我把這個包裝在一個媒體查詢中,以防止在XS顯示寬度時懸停...

@media (min-width:768px)
{
    ul.nav li.dropdown:hover > ul.dropdown-menu {
        display: block;    
    }

    .nav .dropdown-menu {
        margin-top: 0;
    }
}

此外,標記中的脫字符不是必需的,只是li下拉類。


為了讓菜單自動停留在懸停狀態,可以使用基本的CSS來實現。 您需要將選擇器設置為隱藏菜單選項,然後將其設置為當適當的li標籤懸停時顯示為塊。 以twitter引導頁面為例,選擇器如下所示:

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

但是,如果您使用Bootstrap的響應功能,則不會希望在折疊式導航欄上(小屏幕上)使用此功能。 為了避免這種情況,請將上面的代碼包裝在媒體查詢中:

@media (min-width: 979px) {
  ul.nav li.dropdown:hover > ul.dropdown-menu {
    display: block;
  }
}

要隱藏箭頭(插入符號),這取決於您使用的是Twitter Bootstrap版本2或更低版本還是版本3:

Bootstrap 3

要在版本3中刪除插入符號,只需從.dropdown-toggle錨點元素中刪除HTML <b class="caret"></b>

<a class="dropdown-toggle" data-toggle="dropdown" href="#">
    Dropdown
    <b class="caret"></b>    <-- remove this line
</a>

Bootstrap 2和更低

要在版本2中刪除插入符號,您需要對CSS有更深入的了解,並且建議查看:after偽元素如何更詳細地工作。 為了讓你開始理解,在twitter引導示例中定位並移除箭頭,可以使用以下CSS選擇器和代碼:

a.menu:after, .dropdown-toggle:after {
    content: none;
}

如果你進一步研究這些工作的方式,而不是僅僅使用我給你的答案,它將對你有利。

感謝@CocaAkat指出我們錯過了“>”子組合器,以防止子菜單顯示在父項目上


這可能是一個愚蠢的想法,但只要刪除指向下的箭頭,就可以刪除

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

這對於向上指向的人沒有任何幫助,但是......


這對我有效:

.dropdown:hover .dropdown-menu {
    display: block;
}

這會隱藏起來的

.navbar .dropdown-menu:before {
   display:none;
}
.navbar .dropdown-menu:after {
   display:none;
}

這裡有很多非常好的解決方案。 但我認為我會繼續前進,並將其作為另一種選擇放在這裡。 這只是一個簡單的jQuery代碼片段,它可以像引導程序那樣支持懸停而不是點擊鼠標。 我只用版本3測試過,所以我不知道它是否可以與版本2一起工作。將它作為代碼片段保存在你的編輯器中,並在一個關鍵幀處理它。

<script>
    $(function() {
        $(".dropdown").hover(
            function(){ $(this).addClass('open') },
            function(){ $(this).removeClass('open') }
        );
    });
</script>

基本上,它只是說當你將鼠標懸停在下拉類上時,它會將開放類添加到它。 然後它就可以工作。 當您停止在具有下拉類或子級ul / li的父li上懸停時,它將移除打開的類。 顯然,這只是眾多解決方案中的一種,您可以添加它以使其僅適用於.dropdown的特定實例。 或者向父母或子女添加轉換。


還增加了margin-top:0來重置.dropdown菜單的bootstrap css margin,這樣當用戶從下拉菜單緩慢地移動到菜單列表時,菜單列表不會消失。

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

.nav .dropdown-menu {
    margin-top: 0;
}

除了“我的頭痛”(這很棒)的回答之外:

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

有兩個懸而未決的問題:

  1. 點擊下拉鍊接將打開下拉菜單。 它會保持打開狀態,除非用戶在其他地方點擊,或者回過頭來創建一個尷尬的用戶界面。
  2. 下拉鍊接和下拉菜單之間有1px的餘量。 這會導致下拉菜單在下拉菜單和下拉菜單之間緩慢移動時隱藏。

(1)的解決方案是從導航鏈接中刪除“class”和“data-toggle”元素

<a href="#">
     Dropdown
     <b class="caret"></b>
</a>

這也使您能夠創建一個鏈接到您的父頁面 - 這是默認實現不可能的。 您可以將“#”替換為要發送給用戶的任何頁面。

(2)的解決方案是刪除.dropdown菜單選擇器上的margin-top

.navbar .dropdown-menu {
 margin-top: 0px;
}






twitter-bootstrap