Cách tạo menu thả xuống Twitter Bootstrap khi di chuột thay vì nhấp


1181

Tôi muốn để menu Bootstrap của tôi tự động thả xuống khi di chuột, thay vì phải nhấp vào tiêu đề menu. Tôi cũng muốn mất những mũi tên nhỏ bên cạnh tiêu đề menu.


9
Có một giải pháp cho điều đó, vì vậy câu trả lời của mikko là chính xác nhưng hiện tại có một plugin dành riêng cho tình huống đó. bootstrap-hover-dropdown
HenryW

2
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 và hoạt động tốt trên iOS và trên các trình duyệt máy tính để bàn hiện đại có các sự kiện chạm. Ngay cả các thuộc tính aria cũng hoạt động tốt với điều đó: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Ujj-Mészáros

Tôi đã thực hiện thả xuống CSS3 thuần túy với thanh điều hướng bootstrap, hãy kiểm tra nó trên DropP CodePen Pure CSS3
Gothburz

18
Suy nghĩ hai lần nếu bạn thực sự cần nó? Bootstrap đang sử dụng cho các trang web thích ứng. Điều đó có nghĩa là chúng cũng sẽ được sử dụng trên các thiết bị có điều khiển cảm ứng. Đó là lý do tại sao nó được thiết kế theo cách này. Không có "di chuột" trên màn hình cảm ứng.
Serj.by

Bản sao có thể có của
Dropstrap

Câu trả lời:


590

Tôi đã tạo một menu thả xuống di chuột thuần túy dựa trên khung Bootstrap mới nhất (v2.0.2) có hỗ trợ nhiều menu con và nghĩ rằng tôi sẽ đăng nó cho người dùng trong tương lai:

body {
  padding-top: 60px;
  padding-bottom: 40px;
}

.sidebar-nav {
  padding: 9px 0;
}

.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;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet" />

<div class="navbar navbar-fixed-top">
  <div class="navbar-inner">
    <div class="container-fluid">
      <a data-target=".nav-collapse" data-toggle="collapse" class="btn btn-navbar">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </a>
      <a href="#" class="brand">Project name</a>
      <div class="nav-collapse">
        <ul class="nav">
          <li class="active"><a href="#">Home</a></li>
          <li><a href="#">Link</a></li>
          <li><a href="#">Link</a></li>
          <li><a href="#">Link</a></li>
          <li class="dropdown">
            <a data-toggle="dropdown" class="dropdown-toggle" href="#">Dropdown <b class="caret"></b></a>
            <ul class="dropdown-menu">
              <li>
                <a href="#">2-level Dropdown <i class="icon-arrow-right"></i></a>
                <ul class="dropdown-menu sub-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 class="nav-header">Nav header</li>
                  <li><a href="#">Separated link</a></li>
                  <li><a href="#">One more separated link</a></li>
                </ul>
              </li>
              <li><a href="#">Another action</a></li>
              <li><a href="#">Something else here</a></li>
              <li class="divider"></li>
              <li class="nav-header">Nav header</li>
              <li><a href="#">Separated link</a></li>
              <li><a href="#">One more separated link</a></li>
            </ul>
          </li>
        </ul>
        <form action="" class="navbar-search pull-left">
          <input type="text" placeholder="Search" class="search-query span2">
        </form>
        <ul class="nav pull-right">
          <li><a href="#">Link</a></li>
          <li class="divider-vertical"></li>
          <li class="dropdown">
            <a class="#" href="#">Menu</a>
          </li>
        </ul>
      </div>
      <!-- /.nav-collapse -->
    </div>
  </div>
</div>

<hr>

<ul class="nav nav-pills">
  <li class="active"><a href="#">Regular link</a></li>
  <li class="dropdown">
    <a href="#" data-toggle="dropdown" class="dropdown-toggle">Dropdown <b class="caret"></b></a>
    <ul class="dropdown-menu" id="menu1">
      <li>
        <a href="#">2-level Menu <i class="icon-arrow-right"></i></a>
        <ul class="dropdown-menu sub-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 class="nav-header">Nav header</li>
          <li><a href="#">Separated link</a></li>
          <li><a href="#">One more separated link</a></li>
        </ul>
      </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>
  </li>
  <li class="dropdown">
    <a href="#">Menu</a>
  </li>
  <li class="dropdown">
    <a href="#">Menu</a>
  </li>
</ul>

Bản giới thiệu


54
đó là một quyết định thiết kế trong bootstrap để không mở trình đơn thả xuống trong sự kiện di chuột ...
caarlos0

18
thật tốt Tôi cũng gỡ bỏ class="dropdown-toggle" data-toggle="dropdown"để chỉ cần di chuyển, không nhấp sẽ kích hoạt menu. Lưu ý rằng khi bạn đang sử dụng các kiểu phản hồi, các menu vẫn bị cuốn vào nút nhỏ ở trên cùng bên phải, vẫn được kích hoạt bằng một cú nhấp chuột. Cảm ơn nhiều!
ptim

11
Để tránh tự động thả xuống trên các thiết bị nhỏ hơn (như điện thoại) và chỉ cho phép nó ở độ rộng tối thiểu, ví dụ như 768px làm @media (min-width: 768px) {.dropdown-menu li:hover .sub-menu {visibility: visible;}}@media (min-width: 768px) {.dropdown:hover .dropdown-menu {display: block;}}
Chris Aelbrecht

1
Ngoài ra, để tạo liên kết với trẻ em có thể nhấp, bạn phải xóa "data-toggle = 'dropdown'" trên thẻ <a>.
joan16v

2
Đây là một mã hoạt động với phiên bản Bootstrap 3 mới nhất: jsfiddle.net/sgruenwald/2tt8f8xg
Stefan Gruenwald

910

Để có được menu tự động thả xuống khi di chuột thì điều này có thể đạt được bằng cách sử dụng CSS cơ bản. Bạn cần tìm ra bộ chọn vào tùy chọn menu ẩn và sau đó đặt nó để hiển thị dưới dạng khối khi lithẻ thích hợp được di chuột qua. Lấy ví dụ từ trang bootstrap twitter, bộ chọn sẽ như sau:

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

Tuy nhiên, nếu bạn đang sử dụng các tính năng phản hồi của Bootstrap, bạn sẽ không muốn chức năng này trên thanh điều hướng bị sập (trên màn hình nhỏ hơn). Để tránh điều này, hãy bọc mã ở trên trong truy vấn phương tiện:

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

Để ẩn mũi tên (dấu mũ), việc này được thực hiện theo nhiều cách khác nhau tùy thuộc vào việc bạn đang sử dụng Twitter Bootstrap phiên bản 2 trở xuống hay phiên bản 3:

Bootstrap 3

Để xóa dấu mũ trong phiên bản 3, bạn chỉ cần xóa HTML <b class="caret"></b>khỏi .dropdown-togglephần tử neo:

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

Bootstrap 2 & thấp hơn

Để loại bỏ dấu mũ trong phiên bản 2, bạn cần hiểu rõ hơn một chút về CSS và tôi khuyên bạn nên xem cách :afterphần tử giả hoạt động chi tiết hơn. Để giúp bạn bắt đầu trên con đường tìm hiểu, nhắm mục tiêu và loại bỏ các mũi tên trong ví dụ bootstrap của twitter, bạn sẽ sử dụng bộ chọn và mã CSS sau đây:

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

Nó sẽ hoạt động có lợi cho bạn nếu bạn nhìn sâu hơn vào cách thức hoạt động của những thứ này và không chỉ sử dụng các câu trả lời mà tôi đã đưa ra cho bạn.

Cảm ơn @CocaAkat đã chỉ ra rằng chúng tôi đã thiếu trình kết hợp con ">" để ngăn các menu phụ được hiển thị trên di chuột chính


79
Cũng phải thêm margin: 0;, nếu không, lề 1px ở trên .dropdown-menugây ra hành vi lỗi.
Salman von Abbas

12
Giải pháp đơn giản, nhưng liên kết cha mẹ vẫn không thể nhấp được. Tôi đang sử dụng bootstrap mới nhất với chủ đề gốc.
Krunal

5
Lưu ý: Có, nó sẽ hoạt động trong mọi trình duyệt mà twitter bootstrap hỗ trợ. @GeorgeEdison Đây là CSS cơ bản - phần nào sẽ không được IE8 hỗ trợ? Nếu bạn đang gặp vấn đề, hãy đăng một câu hỏi, không bình luận sai lệch.
Đầu tôi đau

3
@MyHeadHurts: Sau một số nghiên cứu sâu hơn - hóa ra đây thực sự là một lỗi Bootstrap và nó chỉ được sửa năm ngày trước.
Nathan Osman

5
@Krunal để có thể nhấp vào liên kết, bạn phải xóa data-toggle="dropdown"thuộc tính.
Pherrymason

230

Ngoài câu trả lời từ "My Head Hurts" (rất hay):

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

Có 2 vấn đề còn sót lại:

  1. Nhấp vào liên kết thả xuống sẽ mở menu thả xuống. Và nó sẽ vẫn mở trừ khi người dùng nhấp vào một nơi khác hoặc di chuyển qua lại, tạo ra một giao diện người dùng khó xử.
  2. Có một lề 1px giữa liên kết thả xuống và menu thả xuống. Điều này làm cho menu thả xuống bị ẩn nếu bạn di chuyển chậm giữa menu thả xuống và menu thả xuống.

Giải pháp cho (1) là loại bỏ các yếu tố "lớp" và "chuyển đổi dữ liệu" khỏi liên kết điều hướng

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

Điều này cũng cung cấp cho bạn khả năng tạo liên kết đến trang mẹ của bạn - điều không thể thực hiện được với việc triển khai mặc định. Bạn chỉ có thể thay thế "#" bằng bất kỳ trang nào bạn muốn gửi cho người dùng.

Giải pháp cho (2) là loại bỏ phần lề trên trên bộ chọn menu .dropdown-menu

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

15
Để sửa lỗi nhấp chuột có chủ ý, tôi chỉ cần xóa data-toggle="dropdown"thuộc tính, có vẻ như hoạt động.
Anthony Briggs

5
Giải pháp (2) cho các nút điều hướng:.nav-pills .dropdown-menu { margin-top: 0px; }
Loren

1
Để khắc phục sự cố tôi đã lưu ý ở trên li.dropdown: hover> ul.dropdown-menu
Archimedes Trajano

12
xóa các thuộc tính "lớp" và "chuyển đổi dữ liệu" khỏi các liên kết điều hướng làm cho nó ngừng hoạt động tốt trên thiết bị di động và máy tính bảng :(
Mosijava

1
Nếu bạn đã xóa thuộc tính data-toggle = "dropdown", bạn sẽ không thể mở rộng menu thả xuống bằng bàn phím. Vì vậy, nó sẽ không tuân thủ 508. Làm thế nào bạn có thể vô hiệu hóa nhấp chuột nhưng vẫn giữ chức năng bàn phím?
duyn9uyen 14/07/2015

130

Tôi đã sử dụng một chút 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();
});

13
Như thế này. Dù sao, việc sử dụng JQuery với công cụ Bootstrap và vẫn cho phép chức năng 'nhấp chuột' mặc định trong các thiết bị màn hình cảm ứng.
Vịt ở Custard

Đã sử dụng cái này. Tôi thích rằng nó vẫn cho phép chức năng nhấp chuột, đối với điện thoại di động, nhưng đối với máy tính để bàn, di chuột là hoàn hảo.
Stuart

1
Tôi đã sử dụng cái này nhưng cũng mở rộng nó để có thể sử dụng cho những lần thả xuống không có trong một điều hướng. Tôi thêm lớp thả xuống-hover vào div nhóm btn và sử dụng công cụ tìm jQuery này $ ('ul.nav li.dropdown, .dropdown-hover'). Hover (function () {. Cảm ơn!
Brandon

Đã sử dụng cái này, đẹp và nhỏ. Phiên bản css không cho phép menu con hiển thị và 200ms quá nhanh nên tôi đã đổi nó thành $('ul.nav li.dropdown').hover(function() { $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(); }, function() { $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut().hover(function() { $(this).stop(true, true); }); });: Khi menu con đang di chuột dừng fadeOut
Damien

điều này dường như không hoạt động với jqLite được bao gồm với anguraljs
nuander

70

Có rất nhiều giải pháp thực sự tốt ở đây. Nhưng tôi nghĩ rằng tôi sẽ đi trước và đưa tôi vào đây như một sự thay thế khác. Đây chỉ là một đoạn mã jQuery đơn giản thực hiện theo cách bootstrap nếu nó được hỗ trợ di chuột cho thả xuống thay vì chỉ nhấp chuột. Tôi chỉ thử nghiệm phiên bản này với phiên bản 3 vì vậy tôi không biết liệu nó có hoạt động với phiên bản 2. Lưu nó dưới dạng một đoạn trong trình chỉnh sửa của bạn và có nó trong một lần nhấn phím.

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

Về cơ bản, nó chỉ nói khi bạn di chuột vào lớp thả xuống, nó sẽ thêm lớp mở vào nó. Sau đó, nó chỉ hoạt động. Khi bạn dừng di chuột trên li cha mẹ với lớp thả xuống hoặc ul / li của con, nó sẽ loại bỏ lớp mở. Rõ ràng, đây chỉ là một trong nhiều giải pháp và bạn có thể thêm vào nó để làm cho nó hoạt động chỉ trong các trường hợp cụ thể của .dropdown. Hoặc thêm một chuyển đổi cho cha mẹ hoặc con cái.


2
Giải pháp tuyệt vời! Tôi cũng đã xóa thuộc tính data-toggle = "dropdown" khỏi liên kết để làm cho liên kết hàng đầu có thể nhấp được.
Sergey

Đó là một mẹo hay đấy. Tôi luôn đảm bảo rằng liên kết hàng đầu không đi đến đâu để nó hoạt động trên máy tính bảng và điện thoại.
lập thể

1
@Sergey Tôi không khuyên bạn nên làm điều đó. Bạn sẽ phá vỡ chức năng cho người dùng di động. Họ không thể sử dụng chức năng di chuột để mở menu và cần có thể nhấp vào nó.
Paul

2
Điều này là ngắn đáng kinh ngạc và dễ dàng trong khi vẫn tương thích ngược với màn hình cảm ứng. Nên được nâng cao hơn nhiều.
Tối đa

Điều này có vẻ thực sự tốt. Bất kỳ ý tưởng làm thế nào để thêm một chút hình ảnh động bằng cách sử dụng chuyển tiếp CSS?
Fred Rocha

69

Chỉ cần tùy chỉnh kiểu CSS của bạn theo ba dòng mã

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

22

Nếu bạn có một phần tử với một dropdownlớp như thế này (ví dụ):

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

Sau đó, bạn có thể để menu thả xuống tự động thả xuống khi di chuột qua, thay vì phải nhấp vào tiêu đề của nó, bằng cách sử dụng đoạn mã jQuery này:

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

Đây là một bản demo

Câu trả lời này dựa trên câu trả lời @Michael , tôi đã thực hiện một số thay đổi và thêm một số bổ sung để trình đơn thả xuống hoạt động đúng


Hoàn hảo. Cảm ơn rất nhiều.
antikbd

20

[Cập nhật] Plugin trên GitHub và tôi đang nghiên cứu một số cải tiến (như chỉ sử dụng với các thuộc tính dữ liệu (không cần sử dụng JS). Tôi đã để lại mã bên dưới, nhưng nó không giống với những gì trên GitHub.

Tôi thích phiên bản CSS hoàn toàn, nhưng thật tuyệt khi có độ trễ trước khi đóng, vì nó thường là trải nghiệm người dùng tốt hơn (nghĩa là không bị phạt vì trượt chuột 1 px bên ngoài thả xuống, v.v.) và như đã đề cập trong các nhận xét , có 1px lề bạn phải xử lý hoặc đôi khi điều hướng đóng bất ngờ khi bạn chuyển sang thả xuống từ nút ban đầu, v.v.

Tôi đã tạo một plugin nhỏ nhanh chóng mà tôi đã sử dụng trên một vài trang web và nó hoạt động rất tốt. Mỗi mục điều hướng được xử lý độc lập, do đó chúng có bộ định thời gian trễ riêng, v.v.

Mã não

// 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);
        });
    });
};  

Các delaytham số là khá tự giải thích, và instantlyCloseOtherssẽ ngay lập tức đóng tất cả các Dropdowns khác được mở ra khi bạn di chuột qua một hình mới.

Không phải CSS thuần túy, nhưng hy vọng sẽ giúp được người khác vào cuối giờ này (tức là đây là một chủ đề cũ).

Nếu bạn muốn, bạn có thể xem các quy trình khác nhau mà tôi đã trải qua (trong một cuộc thảo luận về #concrete5IRC) để làm cho nó hoạt động thông qua các bước khác nhau trong ý chính này: https://gist.github.com/3876924

Cách tiếp cận mẫu plugin sạch hơn nhiều để hỗ trợ các bộ định thời riêng lẻ, v.v.

Xem bài viết trên blog để biết thêm.


16

Điều này làm việc cho tôi:

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

1
Tuy nhiên, với điện thoại di động - thật lạ.
Phóng xạ

Lề giữa menu và menu thả xuống làm cho điều này trở nên vô dụng.
antikbd

15

Điều này được tích hợp vào Bootstrap 3. Chỉ cần thêm phần này vào CSS của bạn:

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

10

Thậm chí tốt hơn với 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');
});

3
Tôi đã thay đổi mã của bạn thành jQuery('ul.nav li.dropdown').hover(function() { jQuery(this).closest('.dropdown-menu').stop(true, true).show(); jQuery(this).addClass('open'); }, function() { jQuery(this).closest('.dropdown-menu').stop(true, true).hide(); jQuery(this).removeClass('open'); });để menu con sẽ không được hiển thị trên di chuột.
farjam

Mã này sẽ không hoạt động nữa với các bản phát hành mới nhất.
Paul

9

Bạn có thể sử dụng $().dropdown('toggle')phương thức mặc định để chuyển đổi menu thả xuống khi di chuột:

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

9

Chỉ muốn thêm, rằng nếu bạn có nhiều danh sách thả xuống (như tôi làm), bạn nên viết:

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

Và nó sẽ hoạt động đúng.


Menu .dropdown của tôi có margin: 2px 0 0;nghĩa là một con chuột chậm. Từ trên xuống ẩn menu sớm. ul.dropdown-menu{ margin-top: 0; }
Alastair

8

Theo tôi cách tốt nhất là như thế này:

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

Đánh dấu mẫu:

<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
Đây là công việc Cameron Spear, nghĩ rằng tôi muốn cho anh Shoutout: cameronspear.com/blog/bootstrap-dropdown-on-hover-plugin
chó lai giống

8

Cách tốt nhất để làm điều đó là chỉ kích hoạt sự kiện nhấp chuột của Bootstrap 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'); 
});

Kết quả không mong muốn: mousein, nhấp và mouseout sẽ để menu mở. Đây không phải là điều tôi muốn ...
Wietse 23/12/14

Sử dụng cái này, Nó chạy hàm bootstrap để mở trình đơn thả xuống, Hàm đó làm nhiều việc khác, như aria-
extend

7

Tôi đã quản lý nó như sau:

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

Tôi hi vọng điêu nay se giup được ai đo...


5

Đồng thời thêm lề-top: 0 để đặt lại lề css bootstrap cho menu .dropdown để danh sách menu không biến mất khi người dùng di chuyển chậm từ menu thả xuống vào danh sách menu.

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

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

2
Đây là câu trả lời đúng, bootstrap đã sẵn sàng để di chuột khi thả xuống, nếu chuột không nằm ngoài menu thả xuống. Loại bỏ lề trên cho phép đi từ liên kết đến menu mà không bị ngắt và do đó không tự động đóng menu. Và giải pháp này cho phép giữ hành vi chính xác cho các thiết bị cảm ứng
Nicolas Janel

5

Đây có lẽ là một ý tưởng ngu ngốc, nhưng để loại bỏ mũi tên chỉ xuống, bạn có thể xóa

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

Điều này không có gì cho người chỉ lên, mặc dù ...


5

Tôi đã xuất bản một plugin thích hợp cho chức năng di chuột thả xuống Bootstrap 3, 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ử (nhấp có thể bị tắ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.

Các js đang can thiệp vào việc nhấp vào .dropdown-toggle, vì vậy trình đơn thả xuống hiển thị khi di chuột, sau đó ẩn nó khi nhấp vào trình đơn thả xuống đã mở và di chuyển chuột sẽ kích hoạt trình đơn thả xuống để hiển thị lại. Một số giải pháp js đang phá vỡ 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 đang 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 . Ngay cả các thuộc tính của Aria cũng hoạt động tốt với plugin này.


Ý kiến ​​của bạn về github.com/vadikom/smartmenus là gì? Tôi không thể quyết định, cả hai thư viện dường như thực sự tốt.
Csaba Toth

2
Smartmenus trông thực sự tốt, nó có thể tốt hơn cho các menu. Plugin của tôi chỉ là một bổ sung nhỏ cho trình đơn thả xuống bootstrap, nó không khác gì mở trình đơn thả xuống khi di chuột, trong khi smartmenu cũng hỗ trợ các menu con và thực hiện một số điều thú vị khác.
István Ujj-Mészáros

1
Cảm ơn. Tôi thấy rằng mã của smartmenu rất rộng và cũng có rất nhiều CSS. Cho đến nay tôi đã đi với bootstrap-dropdown-hover, bởi vì nó dường như làm công việc và nhỏ gọn hơn. Tôi đang xây dựng một trang đích với thanh điều hướng bên trái.
Csaba Toth

4

Sử dụng mã này để mở menu con trên mousehover (chỉ dành cho máy tính để bàn):

$('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','');
    }
});

Và nếu bạn muốn menu cấp đầu tiên có thể nhấp được, ngay cả trên thiết bị di động, hãy thêm điều này:

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

Menu con (menu thả xuống) sẽ được mở bằng mousehover trên máy tính để bàn và với nhấp / chạm trên thiết bị di động và máy tính bảng. Khi menu con được mở, lần nhấp thứ hai sẽ cho phép bạn mở liên kết. Nhờ có if ($(window).width() > 767), menu con sẽ có chiều rộng toàn màn hình trên thiết bị di động.


Tôi muốn sử dụng mã của bạn, nhưng tôi gặp khó khăn khi làm cho nó hoạt động chính xác. Đầu tiên, làm thế nào để loại bỏ hover () cho thiết bị di động và chỉ sử dụng cái đó cho máy tính để bàn? Khi tôi sử dụng mã của bạn và thay đổi kích thước cửa sổ thành thiết bị di động, tôi có cả chức năng hover () và click (). Nhưng kỳ lạ hơn nữa là ... hành vi này sẽ dừng lại khi tôi làm mới trình duyệt, ha! Bạn có thể chỉ cho tôi cách khắc phục điều này? Tôi cần các menu con trên máy tính để hiển thị trên hover () và nhấp () để hiển thị các menu con trên thiết bị di động mà không phải làm mới trình duyệt ngay cả khi thay đổi kích thước cửa sổ để hoạt động chính xác. Tôi hy vọng điều này là rõ ràng
Chris22

ok, điều đó có ý nghĩa và tôi sẽ thử chạy giải pháp của bạn theo cách bạn đề xuất. Cảm ơn!
Chris22

Sử dụng phương pháp tốt nhất này: @falter
Farhad Sakhaei


3

Điều này sẽ ẩn những người lên

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

3

Điều này sẽ che giấu các thả xuống và dấu mũ của chúng nếu chúng nhỏ hơn một máy tính bảng.

@media (max-width: 768px) {
    .navbar ul.dropdown-menu, .navbar li.dropdown b.caret {
        display: none;
    }
}

Tại sao bạn muốn che giấu nó? Bây giờ người dùng di động không có cách nào để truy cập các liên kết trong menu con. Tốt hơn hết là tắt hiệu ứng di chuột trên thiết bị di động và giữ nguyên menu thả xuống. Bằng cách đó họ có thể mở nó bằng cách nhấp vào nó.
Paul

3

Giải pháp jQuery là tốt, nhưng nó sẽ cần phải xử lý các sự kiện nhấp chuột (đối với thiết bị di động hoặc máy tính bảng) vì di chuột sẽ không hoạt động chính xác ... Có thể phát hiện kích thước lại cửa sổ không?

Câu trả lời của Andres Ilich dường như hoạt động tốt, nhưng nó nên được gói gọn trong một truy vấn truyền thông:

@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;
    }
}

3

Giải pháp rất đơn giản cho phiên bản 2, chỉ CSS. Giữ các chức năng thân thiện như nhau cho điện thoại di động và máy tính bảng.

@media (min-width: 980px) {
    .dropdown:hover .dropdown-menu {
       display: block;
    }
}

Điều này không hoạt động tốt cho một số chủ đề trong đó có một khoảng cách giữa mục menu và menu thả xuống. Menu sẽ biến mất khi chuột di chuyển vào khoảng trống này.
ndbroadbent

2

Ghi đè bootstrap.js bằng tập lệnh này.

jQuery(document).ready(function ($) {
$('.navbar .dropdown').hover(function() {
    $(this).addClass('extra-nav-class').find('.dropdown-menu').first().stop(true, true).delay(250).slideDown();
}, function() {
    var na = $(this)
    na.find('.dropdown-menu').first().stop(true, true).delay(100).slideUp('fast', function(){ na.removeClass('extra-nav-class') })
});

$('.dropdown-submenu').hover(function() {
    $(this).addClass('extra-nav-class').find('.dropdown-menu').first().stop(true, true).delay(250).slideDown();
}, function() {
    var na = $(this)
    na.find('.dropdown-menu').first().stop(true, true).delay(100).slideUp('fast', function(){ na.removeClass('extra-nav-class') })
});

}); 

2

Đây là kỹ thuật của tôi có thêm một chút chậm trễ trước khi menu bị đóng sau khi bạn dừng di chuột trên menu hoặc nút chuyển đổi. Cái <button>mà bạn thường nhấp để hiển thị menu nav là #nav_dropdown.

$(function() {
  var delay_close_it, nav_menu_timeout, open_it;
  nav_menu_timeout = void 0;
  open_it = function() {
    if (nav_menu_timeout) {
      clearTimeout(nav_menu_timeout);
      nav_menu_timeout = null;
    }
    return $('.navbar .dropdown').addClass('open');
  };
  delay_close_it = function() {
    var close_it;
    close_it = function() {
      return $('.navbar .dropdown').removeClass('open');
    };
    return nav_menu_timeout = setTimeout(close_it, 500);
  };
  $('body').on('mouseover', '#nav_dropdown, #nav_dropdown *', open_it).on('mouseout', '#nav_dropdown', delay_close_it);
  return $('body').on('mouseover', '.navbar .dropdown .dropdown-menu', open_it).on('mouseout', '.navbar .dropdown .dropdown-menu', delay_close_it);
});

2

Để nâng cao câu trả lời của Sudharshan , tôi bọc câu hỏi này trong truy vấn phương tiện để ngăn di chuột khi trên độ rộng màn hình XS ...

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

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

Ngoài ra, dấu mũ trong đánh dấu là không cần thiết, chỉ cần lớp thả xuống cho li .


2

Điều này hoạt động cho WordPress Bootstrap:

.navbar .nav > li > .dropdown-menu:after,
.navbar .nav > li > .dropdown-menu:before {
    content: none;
}

2

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 một sự kiện nhấp chuột và bạn muốn nó hoạt động trên một 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 100 ms. 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.

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.