Bootstrap Dropdown với Hover


179

OK, vì vậy những gì tôi cần là khá đơn giản.

Tôi đã thiết lập một thanh điều hướng với một số menu thả xuống trong đó (và sử dụng class="dropdown-toggle" data-toggle="dropdown") và nó hoạt động tốt.

Có điều là nó hoạt động " onClick", trong khi tôi thích hơn nếu nó hoạt động " onHover".

Có cách nào tích hợp để làm điều này?


Xem plugin thích hợp mới được xuất bản của tôi để ngăn các sự cố của các giải pháp CSS và js bên dưới: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Ujj-Mészáros

Câu trả lời:


338

Giải pháp đơn giản nhất sẽ là CSS. Thêm một cái gì đó như ...

.dropdown:hover .dropdown-menu {
    display: block;
    margin-top: 0; // remove the gap so it doesn't close
 }

Fiddle làm việc


3
Vì vậy, tốt hơn nhiều so với các giải pháp 'xây dựng đầy đủ' dài. Chỉ cần thêm cái này và thả xuống 'nhấp chuột' mặc định hoạt động trên di chuột mà không cần thay đổi thêm.
IamFace

47
Điều này sẽ xung đột với menu di động có thể thu gọn, vì vậy bạn nên bọc nó trong một điểm dừng @media (min-width: 480px)
Billy Shih

7
Cũng đáng chú ý: nếu bạn có menu thả xuống với các mối quan hệ cha-con, ví dụ trong chủ đề wordpress, bạn cần xóa data-togglethuộc tính để làm cho mục cha mẹ có thể nhấp vào ... Chỉ cần xem ra thiệt hại tài sản thế chấp trên màn hình di động.
Hoàng tử Ken

2
Có một số cách dễ dàng để vô hiệu hóa hiển thị khi nhấp và chỉ giữ hành vi di chuột?
Micer

1
@Micer, tôi vừa xuất bản một plugin trong đó bạn có thể vô hiệu hóa sự kiện nhấp chuột. Plugin hoạt động mà không cần hack CSS, chỉ sử dụng API javascript Bootstrap, do đó, nó tương thích với tất cả các thiết bị: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Ujj-Mészáros

66

Cách tốt nhất để làm điều đó là chỉ kích hoạt sự kiện nhấp chuột bootstraps bằng di chuột. Bằng cách này, nó vẫn nên thân thiện với thiết bị cảm ứng

$('.dropdown').hover(function(){ 
  $('.dropdown-toggle', this).trigger('click'); 
});

1
thất bại nếu bạn có nhiều hơn một cấp độ thả xuống
Connie DeCinko

1
Không hoạt động với liên kết cha mẹ
pio

Có cách nào để loại bỏ lớp Active sau khi đóng cửa thả xuống không?
cân não

Có một khoảng cách pixel giữa thành phần thả xuống và menu có thể khiến menu bị ẩn đi đôi khi, trừ khi bạn nhanh chóng
Matt

1
Sử dụng nhiều danh sách thả xuống cần một số bộ lọc 'gần nhất'.
err

57

Bạn có thể sử dụng chức năng di chuột của jQuery.

Bạn chỉ cần thêm lớp openkhi chuột vào và xóa lớp khi chuột rời khỏi trình đơn thả xuống.

Đây là mã của tôi:

$(function(){
    $('.dropdown').hover(function() {
        $(this).addClass('open');
    },
    function() {
        $(this).removeClass('open');
    });
});

10
Cách tốt hơn thì imho trả lời. Điều này giữ cho tất cả logic bootstrap và kiểu dáng nguyên vẹn. Mặc dù tôi khuyên bạn nên sử dụng cuộc gọi lại lần thứ hai và sử dụng removeClass và addClass một cách rõ ràng để ngăn chặn một số hành vi nghiêm trọng hơn khi bạn nhấp vào nút (nơi nó sẽ mở khi bạn rời nút và đóng khi bạn nhập nó).
Bastiaan Linders

3
Tôi cũng nghĩ rằng đây là câu trả lời tốt nhất. Để làm cho nó hoạt động với menu Bootstrap 4, tôi đã phải sử dụng showthay vì openvà cũng bao gồm dropdown-menu: $('.dropdown').hover(function() { $(this).addClass('show'); $(this).find('.dropdown-menu').addClass('show');}, function() {$(this).removeClass('show'); $(this).find('.dropdown-menu').removeClass('show');});(Xin lỗi vì định dạng.)
Robin Zimmermann

Đừng làm việc nếu bạn có hai mục menu thả xuống. Khi di chuột vào bất kỳ mục thả xuống nào sẽ hiển thị cả hai menu con
Juan Antonio Tubío

23

Một cách dễ dàng, sử dụng jQuery, là:

$(document).ready(function(){
    $('ul.nav li.dropdown').hover(function() {
      $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(200);
    }, function() {
      $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(200);
    });  
});

Tôi thích quá trình chuyển đổi suôn sẻ, tuy nhiên nó khiến tất cả các cấp của menu mở rộng thay vì chỉ cấp độ đầu tiên. Tôi không muốn các menu cấp hai xuất hiện cho đến khi tôi di chuột qua cha mẹ của chúng.
Connie DeCinko

1
Để chỉ nhận cấp độ đầu tiên, hãy thêm .first() - $(this).find('.dropdown-menu').first().stop(true, true).delay(200).fadeIn(200);...
JEdot

9

Đối với CSS, nó thật điên rồ khi bạn cũng nhấp vào nó. Đây là mã mà tôi đang sử dụng, nó cũng không thay đổi bất cứ điều gì cho chế độ xem trên thiết bị di động.

$('.dropdown').mouseenter(function(){
    if(!$('.navbar-toggle').is(':visible')) { // disable for mobile view
        if(!$(this).hasClass('open')) { // Keeps it open when hover it again
            $('.dropdown-toggle', this).trigger('click');
        }
    }
});

Một vẻ đẹp! Tx! Các lựa chọn thay thế CSS sẽ không hoạt động trên Bootstrap 3 và hơn thế nữa.
Pedro Ferreira



5

Vì vậy, bạn có mã này:

<a class="dropdown-toggle" data-toggle="dropdown">Show menu</a>

<ul class="dropdown-menu" role="menu">
    <li>Link 1</li>
    <li>Link 2</li> 
    <li>Link 3</li>                                             
</ul>

Thông thường nó hoạt động trên sự kiện nhấp chuột và bạn muốn nó hoạt động trên sự kiện di chuột. Điều này rất đơn giản, chỉ cần sử dụng mã javascript / jquery này:

$(document).ready(function () {
    $('.dropdown-toggle').mouseover(function() {
        $('.dropdown-menu').show();
    })

    $('.dropdown-toggle').mouseout(function() {
        t = setTimeout(function() {
            $('.dropdown-menu').hide();
        }, 100);

        $('.dropdown-menu').on('mouseenter', function() {
            $('.dropdown-menu').show();
            clearTimeout(t);
        }).on('mouseleave', function() {
            $('.dropdown-menu').hide();
        })
    })
})

Điều này hoạt động rất tốt và đây là lời giải thích: chúng tôi có một nút, và một menu. Khi chúng ta di chuột vào nút, chúng ta sẽ hiển thị menu và khi chúng ta di chuột ra khỏi nút, chúng ta sẽ ẩn menu sau 100ms. Nếu bạn tự hỏi tại sao tôi sử dụng nó, là bởi vì bạn cần thời gian để kéo con trỏ từ nút trên menu. Khi bạn ở trên menu, thời gian được đặt lại và bạn có thể ở đó bao nhiêu lần tùy ý. Khi bạn thoát menu, chúng tôi sẽ ẩn menu ngay lập tức mà không có thời gian chờ.

Tôi đã sử dụng mã này trong nhiều dự án, nếu bạn gặp bất kỳ vấn đề nào khi sử dụng nó, vui lòng đặt câu hỏi cho tôi.


Mã này có rất nhiều vấn đề trên bootstrap v3. 1.) Nếu có nhiều hơn một lần thả xuống, tất cả các lần thả xuống được hiển thị khi bất kỳ được thả xuống. 2.) Trên màn hình nhỏ, di chuột cho thấy thả xuống một cách kỳ lạ.
Thuyền kayak

4

Đây là những gì tôi sử dụng để làm cho nó thả xuống khi di chuột với một số jQuery

$(document).ready(function () {
    $('.navbar-default .navbar-nav > li.dropdown').hover(function () {
        $('ul.dropdown-menu', this).stop(true, true).slideDown('fast');
        $(this).addClass('open');
    }, function () {
        $('ul.dropdown-menu', this).stop(true, true).slideUp('fast');
        $(this).removeClass('open');
    });
});

Đẹp nhưng không hỗ trợ menu phụ.
Connie DeCinko

3

Hãy thử điều này bằng cách sử dụng chức năng di chuột với hình ảnh động mờ dần

$('ul.nav li.dropdown').hover(function() {
  $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(500);
}, function() {
  $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(500);
});

Hoạt hình này không hoạt động ở độ sâu thứ 3 nhưng nó hoạt động ở độ sâu thứ 2. Bạn có giải pháp nào khác cho chiều sâu thứ 3 không?
Jilani A

vui lòng thêm JSFiddle để tham khảo
Rakesh Vadnal

2

Điều này sẽ giúp bạn tạo lớp di chuột của riêng bạn cho bootstrap:

CSS:

/* Hover dropdown */
.hover_drop_down.input-group-btn ul.dropdown-menu{margin-top: 0px;}/*To avoid unwanted close*/
.hover_drop_down.btn-group ul.dropdown-menu{margin-top:2px;}/*To avoid unwanted close*/
.hover_drop_down:hover ul.dropdown-menu{
   display: block;
}

Lợi nhuận được đặt để tránh đóng không mong muốn và chúng là tùy chọn.

HTML:

<div class="btn-group hover_drop_down">
  <button type="button" class="btn btn-default" data-toggle="dropdown"></button>
  <ul class="dropdown-menu" role="menu">
    ...
  </ul>
</div>

Đừng quên xóa thuộc tính nút data-toggle = "dropdown" nếu bạn muốn xóa onclick mở và điều này cũng sẽ hoạt động khi đầu vào được nối với thả xuống.


2

Điều này chỉ di chuyển thanh điều hướng khi bạn không ở trên thiết bị di động, vì tôi thấy rằng việc điều hướng di chuột không hoạt động tốt trên các thiết bị di động:

    $( document ).ready(function() {

    $( 'ul.nav li.dropdown' ).hover(function() {
        // you could also use this condition: $( window ).width() >= 768
        if ($('.navbar-toggle').css('display') === 'none' 
            && false === ('ontouchstart' in document)) {

            $( '.dropdown-toggle', this ).trigger( 'click' );
        }
    }, function() {
        if ($('.navbar-toggle').css('display') === 'none'
            && false === ('ontouchstart' in document)) {

            $( '.dropdown-toggle', this ).trigger( 'click' );
        }
    });

});

Bạn có thể tìm thấy một giải pháp tốt hơn nhiều ở đây: github.com/CWSpear/bootstrap-hover-dropdown .
solarbaypilot

2

Tôi thử các giải pháp khác, tôi đang sử dụng bootstrap 3, nhưng menu thả xuống đóng quá nhanh để di chuyển qua nó

giả sử bạn thêm class = "dropdown" vào li, tôi đã thêm thời gian chờ

var hoverTimeout;
$('.dropdown').hover(function() {
    clearTimeout(hoverTimeout);
    $(this).addClass('open');
}, function() {
    var $self = $(this);
    hoverTimeout = setTimeout(function() {
        $self.removeClass('open');
    }, 150);
});

2

Cập nhật với một plugin thích hợp

Tôi đã xuất bản một plugin thích hợp cho chức năng di chuột thả xuống, trong đó bạn thậm chí có thể xác định điều gì sẽ xảy ra khi nhấp vào dropdown-togglephần tử:

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


Tại sao tôi làm nó, khi đã có nhiều giải pháp?

Tôi đã có vấn đề với tất cả các giải pháp hiện có trước đây. Các CSS đơn giản không sử dụng .openlớp trên .dropdown, do đó sẽ không có phản hồi về phần tử chuyển đổi thả xuống khi hiển thị thả xuống.

Những người js đang can thiệp vào nhấp vào .dropdown-toggle , vì vậy trình đơn thả xuống hiển thị trên di chuột, sau đó ẩn nó khi nhấp vào một danh sách thả xuống và di chuyển chuột sẽ kích hoạt thả xuống để hiển thị lại. Một số giải pháp js đang hãm khả năng tương thích iOS, một số plugin không hoạt động trên các trình duyệt máy tính để bàn hiện đại hỗ trợ các sự kiện cảm ứng.

Đó là lý do tại sao tôi tạo plugin Bootstrap Dropdown Hover để ngăn chặn tất cả các vấn đề này bằng cách chỉ sử dụng API javascript Bootstrap tiêu chuẩn mà không cần bất kỳ hack nào.


1
    $('.navbar .dropdown').hover(function() {
      $(this).find('.dropdown-menu').first().stop(true, true).slideDown(150);
    }, function() {
      $(this).find('.dropdown-menu').first().stop(true, true).slideUp(105)
    });

1

Kích hoạt một clicksự kiện với một hoverlỗi nhỏ. Nếu mouse-invà sau đó a clicktạo hiệu ứng ngược lại. Nó openskhi nào mouse-outclosekhi nào mouse-in. Một giải pháp tốt hơn:

$('.dropdown').hover(function() {
    if (!($(this).hasClass('open'))) {
        $('.dropdown-toggle', this).trigger('click');
    }
}, function() {
    if ($(this).hasClass('open')) {
        $('.dropdown-toggle', this).trigger('click');
    }
});

1

html

        <div class="dropdown">

            <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
                Dropdown Example <span class="caret"></span>
            </button>

            <ul class="dropdown-menu">
                <li><a href="#">HTML</a></li>
                <li><a href="#">CSS</a></li>
                <li><a href="#">JavaScript</a></li>
            </ul>

        </div> 

jquery

        $(document).ready( function() {                

            /* $(selector).hover( inFunction, outFunction ) */
            $('.dropdown').hover( 
                function() {                        
                    $(this).find('ul').css({
                        "display": "block",
                        "margin-top": 0
                    });                        
                }, 
                function() {                        
                    $(this).find('ul').css({
                        "display": "none",
                        "margin-top": 0
                    });                        
                } 
            );

        });

codepen


0

Giải pháp tôi đang đề xuất phát hiện nếu thiết bị không chạm vào và navbar-toggle(menu hamburger) không hiển thị và làm cho mục menu cha hiển thị menu con khi di chuộttheo liên kết của nó khi nhấp .

Đồng thời làm cho lề trên 0 vì khoảng cách giữa thanh điều hướng và menu trong một số trình duyệt sẽ không cho phép bạn di chuột đến các phụ đề

$(function(){
    function is_touch_device() {
        return 'ontouchstart' in window        // works on most browsers 
        || navigator.maxTouchPoints;       // works on IE10/11 and Surface
    };

    if(!is_touch_device() && $('.navbar-toggle:hidden')){
      $('.dropdown-menu', this).css('margin-top',0);
      $('.dropdown').hover(function(){ 
          $('.dropdown-toggle', this).trigger('click').toggleClass("disabled"); 
      });			
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<ul id="nav" class="nav nav-pills clearfix right" role="tablist">
    <li><a href="#">menuA</a></li>
    <li><a href="#">menuB</a></li>
    <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">menuC</a>
        <ul id="products-menu" class="dropdown-menu clearfix" role="menu">
            <li><a href="">A</a></li>
            <li><a href="">B</a></li>
            <li><a href="">C</a></li>
            <li><a href="">D</a></li>
        </ul>
    </li>
    <li><a href="#">menuD</a></li>
    <li><a href="#">menuE</a></li>
</ul>

$(function(){
  $("#nav .dropdown").hover(
    function() {
      $('#products-menu.dropdown-menu', this).stop( true, true ).fadeIn("fast");
      $(this).toggleClass('open');
    },
    function() {
      $('#products-menu.dropdown-menu', this).stop( true, true ).fadeOut("fast");
      $(this).toggleClass('open');
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<ul id="nav" class="nav nav-pills clearfix right" role="tablist">
    <li><a href="#">menuA</a></li>
    <li><a href="#">menuB</a></li>
    <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">menuC</a>
        <ul id="products-menu" class="dropdown-menu clearfix" role="menu">
            <li><a href="">A</a></li>
            <li><a href="">B</a></li>
            <li><a href="">C</a></li>
            <li><a href="">D</a></li>
        </ul>
    </li>
    <li><a href="#">menuD</a></li>
    <li><a href="#">menuE</a></li>
</ul>


0

Trình đơn thả xuống Bootstrap Làm việc trên di chuột và vẫn đóng khi nhấp bằng cách thêm hiển thị thuộc tính: block; trong css và xóa các thuộc tính này data-toggle = "dropdown" role = "button" khỏi thẻ nút

.dropdown:hover .dropdown-menu {
  display: block;
}
<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
</head>
<body>

<div class="container">                                     
  <div class="dropdown">
    <button class="btn btn-primary dropdown-toggle">Dropdown Example
    <span class="caret"></span></button>
    <ul class="dropdown-menu">
      <li><a href="#">HTML</a></li>
      <li><a href="#">CSS</a></li>
      <li><a href="#">JavaScript</a></li>
    </ul>
  </div>
</div>

</body>
</html>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.