วิธีการทำให้เมนู Bootstrap ของ Twitter หล่นลงบนโฮเวอร์แทนที่จะคลิก


1181

ฉันต้องการให้เมนู Bootstrap ของฉันวางลงบนโฮเวอร์โดยอัตโนมัติแทนที่จะต้องคลิกที่ชื่อเมนู ฉันต้องการจะสูญเสียลูกศรเล็ก ๆ ถัดจากชื่อเมนู


9
มีวิธีแก้ปัญหาสำหรับสิ่งนั้นดังนั้นคำตอบของ mikko นั้นถูกต้อง แต่ครอบคลุมด้วยปลั๊กอินสำหรับสถานการณ์นั้นโดยเฉพาะ bootstrap-hover-dropdown
HenryW

2
ดูปลั๊กอินที่เหมาะสมซึ่งเผยแพร่ใหม่ของฉันซึ่งป้องกันปัญหาของ CSS และ js ด้านล่างและทำงานได้ดีบน iOS และบนเบราว์เซอร์เดสก์ท็อปสมัยใหม่ที่มีกิจกรรมการสัมผัส แม้แต่คุณสมบัติอาเรียก็ยังทำงานได้ดี: github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover
István Ujj-Mészáros

ฉันสร้าง CSS3 แบบเลื่อนลงโดยใช้ bootstrap navbar ลองดูที่ CodePen Pure CSS3 Dropdown
Gothburz

18
คิดสองครั้งถ้าคุณต้องการมันจริงเหรอ? Bootstrap ใช้สำหรับไซต์ที่ปรับเปลี่ยนได้ หมายความว่าพวกมันจะถูกใช้กับอุปกรณ์ที่มีระบบควบคุมแบบสัมผัสเช่นกัน นั่นเป็นเหตุผลที่มันถูกออกแบบด้วยวิธีนี้ ไม่มี "โฮเวอร์" บนหน้าจอสัมผัส
Serj.by

ซ้ำเป็นไปได้ของBootstrap Dropdown กับ Hover
slugster

คำตอบ:


590

ฉันสร้างเมนูแบบเลื่อนลงบริสุทธิ์ตามเฟรมเวิร์ก Bootstrap ล่าสุด (v2.0.2) ที่สนับสนุนเมนูย่อยหลายรายการและคิดว่าฉันจะโพสต์ไว้สำหรับผู้ใช้ในอนาคต:

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>

การสาธิต


54
มันเป็นการตัดสินใจออกแบบใน bootstrap เพื่อไม่เปิด dropdowns ในการโฮเวอร์กิจกรรม ...
caarlos0

18
ดีมาก! ฉันยังลบclass="dropdown-toggle" data-toggle="dropdown"เพื่อให้วนเวียนเพียงไม่คลิกจะเรียกเมนู โปรดทราบว่าเมื่อคุณใช้สไตล์ที่ตอบสนองได้เมนูจะยังคงถูกกวาดเข้าไปในปุ่มเล็ก ๆ ที่ด้านบนขวาซึ่งยังคงถูกกระตุ้นด้วยการคลิก ขอบคุณมาก ๆ!
ptim

11
เพื่อหลีกเลี่ยงการเลื่อนลงอัตโนมัติบนอุปกรณ์ขนาดเล็ก (เช่นโทรศัพท์) และอนุญาตให้ใช้เป็นความกว้างขั้นต่ำเช่น 768px do @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
นอกจากนี้ในการสร้างลิงก์กับเด็ก ๆ ที่คลิกได้คุณต้องลบ "data-toggle = 'dropdown'" บนแท็ก <a>
joan16v

2
นี่คือรหัสที่ทำงานร่วมกับ Bootstrap 3 รุ่นใหม่ล่าสุด: jsfiddle.net/sgruenwald/2tt8f8xg
Stefan Gruenwald

910

หากต้องการให้เมนูเลื่อนโดยอัตโนมัติเมื่อวางเมาส์ไว้เหนือสิ่งนี้สามารถทำได้โดยใช้ CSS พื้นฐาน คุณต้องเลือกตัวเลือกให้เป็นเมนูซ่อนจากนั้นตั้งค่าให้แสดงเป็นบล็อกเมื่อมีการวางliแท็กที่เหมาะสม นำตัวอย่างจากหน้า bootstrap twitter ตัวเลือกจะเป็นดังนี้:

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

อย่างไรก็ตามหากคุณใช้คุณสมบัติตอบสนองของ Bootstrap คุณจะไม่ต้องการฟังก์ชั่นนี้ใน navbar ที่ยุบตัว (บนหน้าจอขนาดเล็ก) เพื่อหลีกเลี่ยงปัญหานี้ให้ห่อโค้ดด้านบนในเคียวรีสื่อบันทึก:

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

ในการซ่อนลูกศร (คาเร็ต) วิธีนี้ทำได้หลายวิธีขึ้นอยู่กับว่าคุณใช้ Twitter Bootstrap เวอร์ชั่น 2 หรือต่ำกว่าหรือรุ่น 3:

Bootstrap 3

หากต้องการลบเครื่องหมายรูปหมวกในเวอร์ชัน 3 คุณเพียงแค่ลบ HTML <b class="caret"></b>ออกจาก.dropdown-toggleองค์ประกอบจุดยึด:

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

Bootstrap 2 และต่ำกว่า

หากต้องการลบเครื่องหมายรูปหมวกในเวอร์ชัน 2 คุณต้องมีความเข้าใจลึกซึ้งยิ่งขึ้นเกี่ยวกับ CSS และฉันขอแนะนำให้ดูว่า:afterองค์ประกอบหลอกทำงานในรายละเอียดมากขึ้น เพื่อให้คุณเริ่มต้นในการทำความเข้าใจในการกำหนดเป้าหมายและลบลูกศรในตัวอย่าง bootstrap twitter คุณจะต้องใช้ตัวเลือก CSS และรหัสต่อไปนี้:

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

มันจะทำงานในความโปรดปรานของคุณถ้าคุณดูเพิ่มเติมว่าวิธีการทำงานเหล่านี้และไม่เพียงแค่ใช้คำตอบที่ฉันได้ให้คุณ

ขอขอบคุณ @CocaAkat ที่ชี้ให้เห็นว่าเราพลาด combinator ลูก ">" เพื่อป้องกันไม่ให้แสดงเมนูย่อยในการโฮเวอร์พาเรนต์


79
ต้องเพิ่มmargin: 0;ด้วยมิฉะนั้นระยะขอบ 1px ด้านบน.dropdown-menuจะทำให้เกิดพฤติกรรมบั๊กกี้
Salman von Abbas

12
วิธีแก้ปัญหาง่าย ๆ แต่ลิงค์ผู้ปกครองนั้นยังไม่สามารถคลิกได้ ฉันใช้ bootstrap ล่าสุดพร้อมกับชุดรูปแบบของ root
Krunal

5
หมายเหตุ:ใช่มันจะทำงานในเบราว์เซอร์ใดก็ได้ที่ twitter bootstrap รองรับ @GeorgeEdison นี่คือ CSS พื้นฐาน - IE8 ส่วนใดที่ไม่รองรับ หากคุณกำลังมีปัญหาโพสต์คำถามไม่ใช่ความคิดเห็นที่ทำให้เข้าใจผิด
หัวของฉันเจ็บ

3
@ MyHeadHurts: หลังจากการวิจัยเพิ่มเติม - ปรากฎว่านี่เป็นข้อผิดพลาด Bootstrapและได้รับการแก้ไขเพียงห้าวันที่ผ่านมา
Nathan Osman

5
@Krunal เพื่อให้สามารถคลิกลิงค์คุณต้องลบdata-toggle="dropdown"แอตทริบิวต์
Pherrymason

230

นอกจากคำตอบจาก "My Head Hurts" (ซึ่งเยี่ยมมาก):

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

มีปัญหาที่เอ้อระเหย 2 ประการ:

  1. คลิกที่ลิงค์แบบเลื่อนลงจะเปิดเมนูแบบเลื่อนลง และมันจะยังคงเปิดอยู่เว้นแต่ผู้ใช้จะคลิกที่อื่นหรือวนเวียนอยู่เหนือมันสร้าง UI ที่น่าอึดอัดใจ
  2. มีระยะขอบ 1px ระหว่างลิงก์แบบเลื่อนลงและเมนูแบบเลื่อนลง สิ่งนี้ทำให้เมนูแบบเลื่อนลงซ่อนหากคุณเคลื่อนไหวช้าระหว่างเมนูแบบเลื่อนลงและเมนูแบบเลื่อนลง

วิธีการ (1) กำลังลบองค์ประกอบ "คลาส" และ "data-toggle" ออกจากลิงก์ nav

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

สิ่งนี้ยังช่วยให้คุณสามารถสร้างลิงก์ไปยังเพจพาเรนต์ของคุณซึ่งไม่สามารถทำได้ด้วยการใช้งานเริ่มต้น คุณสามารถแทนที่ "#" ด้วยหน้าอะไรก็ได้ที่คุณต้องการส่งผู้ใช้

วิธีการ (2) กำลังลบส่วนต่างบนตัวเลือกเมนู. dropdown

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

15
หากต้องการแก้ไขการคลิกโดยเจตนาฉันเพิ่งลบdata-toggle="dropdown"แอตทริบิวต์ซึ่งดูเหมือนว่าจะใช้งานได้
Anthony Briggs

5
โซลูชัน (2) สำหรับปุ่ม nav-pill:.nav-pills .dropdown-menu { margin-top: 0px; }
Loren

1
ในการแก้ไขปัญหาฉันได้กล่าวไว้ข้างต้น li.dropdown: hover> ul.dropdown-menu
Archimedes Trajano

12
การลบแอตทริบิวต์ "คลาส" และ "data-toggle" ออกจากลิงก์ nav ทำให้หยุดทำงานได้ดีในอุปกรณ์พกพาและแท็บเล็ต :(
Mosijava

1
หากคุณลบแอตทริบิวต์ data-toggle = "dropdown" คุณจะไม่สามารถขยายเมนูแบบเลื่อนลงโดยใช้แป้นพิมพ์ ดังนั้นจะไม่เป็นไปตามมาตรฐาน 508 คุณจะปิดการใช้งานการคลิก แต่ใช้ฟังก์ชันคีย์บอร์ดได้อย่างไร
duyn9uyen

130

ฉันใช้ 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
แบบนี้. กำลังใช้ JQuery อยู่แล้วกับสิ่งที่ Bootstrap และยังช่วยให้การทำงาน 'คลิก' เริ่มต้นในอุปกรณ์หน้าจอสัมผัส
เป็ดในสังขยา

ใช้สิ่งนี้ ฉันชอบที่มันยังช่วยให้สามารถใช้งานการคลิกได้เช่นกันสำหรับโทรศัพท์มือถือ แต่สำหรับเดสก์ท็อปโฮเวอร์จะสมบูรณ์แบบ
Stuart

1
ฉันใช้สิ่งนี้ แต่ยังขยายให้ใช้งานได้สำหรับดรอปดาวน์ที่ไม่ได้อยู่ใน nav ฉันเพิ่มคลาสดรอปดาวน์ - โฮเวอร์ไปยังกลุ่ม btn-group และใช้เครื่องมือค้นหา jQuery $ นี้ ('ul.nav li.dropdown,. dropdown-hover') โฮเวอร์ (ฟังก์ชั่น () {ขอบคุณ!
Brandon

ใช้อันนี้ดีและเล็ก เวอร์ชัน css ไม่อนุญาตให้แสดงเมนูย่อยและ 200ms ก็เร็วเกินไปดังนั้นฉันจึงเปลี่ยนเป็น$('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); }); });: เมื่อเมนูย่อยหยุดโฮลด์หยุด fadeOut
Damien

ดูเหมือนจะไม่ทำงานกับ jqLite ที่รวมอยู่กับ anguraljs
nuander

70

มีทางออกที่ดีมากมายที่นี่ แต่ฉันคิดว่าฉันจะไปข้างหน้าและใส่ของฉันที่นี่เป็นทางเลือกอื่น มันเป็นเพียงตัวอย่างง่ายๆของ jQuery ที่ทำตามวิธีการบูทสแตรปหากรองรับ hover สำหรับ dropdowns แทนที่จะคลิก ฉันเพิ่งทดสอบสิ่งนี้กับรุ่น 3 เท่านั้นดังนั้นฉันจึงไม่รู้ว่ามันจะใช้งานได้กับรุ่น 2 หรือไม่บันทึกเป็นตัวอย่างในตัวแก้ไขของคุณ

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

โดยทั่วไปมันเพิ่งจะพูดว่าเมื่อคุณวางเมาส์บนคลาสดร็อปดาวน์มันจะเพิ่มคลาสที่เปิดอยู่ จากนั้นมันก็ใช้งานได้ เมื่อคุณหยุดการวางเมาส์บนพาเรนต์ li พร้อมกับคลาสดร็อปดาวน์หรือ child ul / li's คลาสนั้นจะลบคลาสที่เปิดออก เห็นได้ชัดว่านี่เป็นเพียงหนึ่งในวิธีการแก้ปัญหามากมายและคุณสามารถเพิ่มเข้าไปเพื่อให้มันทำงานบนอินสแตนซ์เฉพาะของ. dropdown หรือเพิ่มช่วงการเปลี่ยนภาพไปที่ผู้ปกครองหรือเด็ก


2
สุดยอดทางออก! ฉันยังลบ data-toggle = "dropdown" คุณลักษณะจากลิงก์เพื่อให้คลิกบนลิงก์ได้
Sergey

นั่นเป็นเคล็ดลับที่ดีสำหรับ Sergey ฉันมักจะตรวจสอบให้แน่ใจว่าลิงค์ด้านบนไปที่ใดก็ได้เพื่อให้สามารถใช้งานได้บนแท็บเล็ตและโทรศัพท์เช่นกัน
ภาพสามมิติ

1
@ Sergey ฉันจะไม่แนะนำให้ทำเช่นนั้น คุณจะทำลายฟังก์ชันการทำงานสำหรับผู้ใช้มือถือ พวกเขาไม่สามารถใช้ฟังก์ชันโฮเวอร์เพื่อเปิดเมนูและต้องสามารถคลิกได้
พอล

2
มันสั้นและง่ายอย่างน่าอัศจรรย์ในขณะที่ยังใช้งานร่วมกับทัชสกรีนได้ ควร upvoted มากขึ้น
สูงสุด

มันดูดีจริงๆ มีความคิดใดที่จะเพิ่มภาพเคลื่อนไหวเล็กน้อยโดยใช้การเปลี่ยน CSS
Fred Rocha

69

เพียงปรับแต่งสไตล์ CSS ของคุณด้วยโค้ดสามบรรทัด

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

22

หากคุณมีองค์ประกอบที่มี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>

นี่คือตัวอย่าง

คำตอบนี้ขึ้นอยู่กับคำตอบของ @Michaelฉันได้ทำการเปลี่ยนแปลงบางอย่างและเพิ่มส่วนเพิ่มเติมบางส่วนเพื่อให้เมนูแบบเลื่อนลงทำงานได้อย่างถูกต้อง


สมบูรณ์ ขอบคุณมาก.
antikbd

20

[อัปเดต]ปลั๊กอินอยู่ในGitHubและฉันกำลังทำการปรับปรุงบางอย่าง (เช่นใช้เฉพาะกับแอตทริบิวต์ข้อมูล (ไม่จำเป็นต้องใช้ JS) ฉันทิ้งโค้ดไว้ด้านล่าง แต่มันไม่เหมือนกับสิ่งที่อยู่ใน GitHub

ฉันชอบรุ่น CSS อย่างหมดจด แต่ก็ดีที่มีความล่าช้าก่อนที่มันจะปิดเพราะมันมักจะเป็นประสบการณ์การใช้งานที่ดีขึ้น (เช่นไม่ถูกลงโทษสำหรับการเลื่อนเมาส์ที่ไป 1 px นอกดรอปดาวน์ ฯลฯ ) และตามที่ระบุไว้ในความคิดเห็น มีระยะขอบ 1px ที่คุณต้องจัดการหรือบางครั้ง nav ปิดโดยไม่คาดคิดเมื่อคุณย้ายไปที่เมนูแบบเลื่อนลงจากปุ่มเดิม ฯลฯ

ฉันสร้างปลั๊กอินเล็ก ๆ น้อย ๆ ที่ฉันใช้ในเว็บไซต์สองแห่งและทำงานได้ดี แต่ละรายการ nav ได้รับการจัดการอย่างอิสระดังนั้นจึงมีตัวจับเวลาการหน่วงเวลาของตัวเอง ฯลฯ

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จะ dropdowns ทันทีใกล้อื่น ๆ ทั้งหมดที่มีการเปิดเมื่อคุณวางเมาส์เหนือใหม่

ไม่ใช่ CSS ที่บริสุทธิ์ แต่หวังว่าจะช่วยให้คนอื่นในเวลาสายนี้ (เช่นนี้เป็นเธรดเก่า)

หากคุณต้องการคุณสามารถเห็นกระบวนการต่าง ๆ ที่ฉันได้ผ่าน (ในการอภิปรายใน#concrete5IRC) เพื่อให้มันทำงานผ่านขั้นตอนต่าง ๆ ในส่วนสำคัญนี้: https://gist.github.com/3876924

แนวทางรูปแบบปลั๊กอินนั้นสะอาดกว่ามากสำหรับการรองรับตัวจับเวลาแต่ละตัว ฯลฯ

ดูโพสต์บล็อกสำหรับข้อมูลเพิ่มเติม


16

สิ่งนี้ใช้ได้กับฉัน:

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

1
ด้วยมือถือ แต่ - มันแปลก
Radmation

ระยะห่างระหว่างเมนูและเมนูแบบเลื่อนลงทำให้ไม่มีประโยชน์
antikbd

15

สิ่งนี้สร้างขึ้นใน Bootstrap 3 เพียงเพิ่มสิ่งนี้ลงใน CSS ของคุณ:

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

10

ดียิ่งขึ้นกับ 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
ฉันเปลี่ยนรหัสของคุณ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'); });เป็นเมนูย่อยเพื่อไม่ให้ปรากฏบนโฮเวอร์
farjam

รหัสนี้จะไม่ทำงานอีกต่อไปกับการเปิดตัวล่าสุด
พอล

9

คุณสามารถใช้$().dropdown('toggle')วิธีการเริ่มต้นเพื่อสลับเมนูดร็อปดาวน์เมื่อโฮเวอร์:

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

9

เพียงแค่ต้องการเพิ่มว่าถ้าคุณมีหลายรายการ (เช่นฉัน) คุณควรเขียน:

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

และมันจะทำงานอย่างถูกต้อง


. dropdown-menu ของฉันmargin: 2px 0 0;ซึ่งแปลว่าเม้าส์ช้าที่ป้อนจากด้านบนซ่อนเมนูไว้ก่อนหน้า ul.dropdown-menu{ margin-top: 0; }
Alastair

8

ในความคิดของฉันวิธีที่ดีที่สุดเป็นเช่นนี้

;(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
นี่คืองานของ Cameron Spear คิดว่าฉันจะให้เขาตะโกน
kelpie

8

วิธีที่ดีที่สุดในการทำคือเพียงแค่ทริกเกอร์เหตุการณ์การคลิกของ Bootstrap ด้วยโฮเวอร์ ด้วยวิธีนี้มันควรจะยังคงสัมผัสอุปกรณ์ที่เป็นมิตร

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

ผลลัพธ์ที่ไม่ต้องการ: mousein, click และ mouseout จะเปิดเมนูค้างไว้ นี่ไม่ใช่สิ่งที่ฉันต้องการ ...
Wietse

การใช้สิ่งนี้มันเรียกใช้ฟังก์ชั่น bootstrap เพื่อเปิดดรอปดาวน์ฟังก์ชั่นนั้นทำสิ่งอื่น ๆ อีกมากมายเช่น aria-
expand


5

เพิ่ม margin-top: 0 เพื่อรีเซ็ต bootstrap css margin สำหรับ. dropdown-menu ดังนั้นรายการเมนูจะไม่หายไปเมื่อผู้ใช้เลื่อนขึ้นจากเมนูแบบเลื่อนลงไปยังรายการเมนู

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

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

2
นี่คือคำตอบที่ถูกต้อง bootstrap พร้อมสำหรับการโฮเวอร์เมื่อดรอปดาวน์หากเมาส์ไม่ออกนอกเมนูดรอปดาวน์ การลบขอบด้านบนอนุญาตให้ไปจากลิงก์ไปยังเมนูโดยไม่หยุดพักและไม่ปิดอัตโนมัติของเมนู และการแก้ปัญหานี้จะช่วยให้การรักษาพฤติกรรมที่ถูกต้องสำหรับอุปกรณ์สัมผัส
นิโคลัสบ้า

5

นี่อาจเป็นแนวคิดที่งี่เง่า แต่หากต้องการลบลูกศรที่ชี้ลงคุณสามารถลบ

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

สิ่งนี้ไม่ทำอะไรเลยสำหรับการชี้ขึ้น ...


5

ฉันได้เผยแพร่ปลั๊กอินที่เหมาะสมสำหรับการทำงานแบบเลื่อนลง Bootstrap 3 ซึ่งคุณสามารถกำหนดสิ่งที่เกิดขึ้นเมื่อคลิกที่dropdown-toggleองค์ประกอบ (การคลิกสามารถปิดใช้งาน):

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


ทำไมฉันทำมันเมื่อมีวิธีแก้ปัญหามากมายอยู่แล้ว?

ฉันมีปัญหากับโซลูชันที่มีอยู่ก่อนหน้านี้ทั้งหมด CSS ง่าย ๆ ไม่ได้ใช้.openคลาสบน.dropdownดังนั้นจะไม่มีความคิดเห็นเกี่ยวกับองค์ประกอบสลับแบบเลื่อนลงเมื่อมองเห็นรายการแบบหล่นลง

js กำลังรบกวนการคลิก .dropdown-toggleเพื่อให้ดรอปดาวน์ปรากฏขึ้นเมื่อโฮเวอร์แล้วซ่อนเมื่อคลิกที่ดรอปดาวน์ที่เปิดอยู่และการเลื่อนเมาส์ออกไปจะเป็นการกระตุ้นให้ดรอปดาวน์ปรากฏขึ้นอีกครั้ง โซลูชัน js บางตัวกำลังทำลายความเข้ากันได้ของ iOS ปลั๊กอินบางตัวไม่ทำงานบนเบราว์เซอร์เดสก์ท็อปสมัยใหม่ที่รองรับการสัมผัส

นั่นเป็นเหตุผลที่ฉันสร้างปลั๊กอินBootstrap Dropdown Hover ซึ่งป้องกันปัญหาเหล่านี้โดยใช้เฉพาะมาตรฐาน Bootstrap javascript API โดยไม่ต้องแฮ็ค แม้แต่แอตทริบิวต์ Aria ก็ยังทำงานได้ดีกับปลั๊กอินนี้


ความคิดเห็นของคุณเกี่ยวกับgithub.com/vadikom/smartmenusคืออะไร? ฉันไม่สามารถตัดสินใจได้ห้องสมุดทั้งสองดูเหมือนจะดีจริงๆ
Csaba Toth

2
Smartmenus ดูดีจริงๆมันอาจจะดีกว่าสำหรับเมนู ปลั๊กอินของฉันเป็นเพียงส่วนเสริมเล็ก ๆ ของ bootstrap ดรอปดาวน์มันไม่เพียงแค่เปิด dropdown บนโฮเวอร์ในขณะที่ smartmenu รองรับเมนูย่อยเช่นกันและทำสิ่งแฟนซีอื่น ๆ
István Ujj-Mészáros

1
ขอบคุณ ฉันเห็นว่าโค้ดของ smartmenu นั้นกว้างขวางมากและมี CSS จำนวนมาก จนถึงตอนนี้ฉันไปด้วยbootstrap-dropdown-hoverเพราะดูเหมือนว่าจะทำงานและมีขนาดกะทัดรัดมากขึ้น ฉันกำลังสร้างเว็บไซต์ที่มีแถบนำทางด้านซ้าย
Csaba Toth

4

ใช้รหัสนี้เพื่อเปิดเมนูย่อยบน 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');
    }
});

เมนูย่อย (เมนูแบบเลื่อนลง) จะเปิดด้วย mousehover บนเดสก์ท็อปและด้วยการคลิก / สัมผัสบนมือถือและแท็บเล็ต เมื่อเมนูย่อยเปิดขึ้นการคลิกครั้งที่สองจะช่วยให้คุณเปิดลิงก์ได้ ขอบคุณif ($(window).width() > 767)เมนูย่อยจะใช้ความกว้างเต็มหน้าจอบนมือถือ


ฉันต้องการใช้รหัสของคุณ แต่ฉันมีปัญหาในการทำให้มันทำงานอย่างถูกต้อง ขั้นแรกจะลบโฮเวอร์ () สำหรับมือถือได้อย่างไรและใช้กับเดสก์ท็อปเท่านั้น เมื่อฉันใช้รหัสของคุณและปรับขนาดหน้าต่างให้เป็นมือถือฉันจะได้รับทั้งฟังก์ชันการใช้โฮเวอร์ () และคลิก () แต่ที่แปลกกว่านั้นคือพฤติกรรมนี้จะหยุดลงเมื่อฉันรีเฟรชเบราว์เซอร์ฮ่า! คุณช่วยแสดงวิธีแก้ไขปัญหาให้ฉันได้ไหม ฉันต้องการเมนูย่อยของเดสก์ท็อปเพื่อแสดงบนโฮเวอร์ () และคลิก () เพื่อแสดงเมนูย่อยบนมือถือโดยไม่ต้องรีเฟรชเบราว์เซอร์แม้ว่าจะปรับขนาดหน้าต่างเพื่อให้ทำงานอย่างถูกต้อง ฉันหวังว่านี่ชัดเจน
Chris22

ตกลงที่เหมาะสมและฉันจะลองใช้โซลูชันของคุณในแบบที่คุณแนะนำ ขอบคุณ!
Chris22

ใช้วิธีการที่ดีที่สุดนี้: @falter
Farhad Sakhaei


3

สิ่งนี้จะซ่อนสิ่งที่ซ่อนอยู่

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

3

การดำเนินการนี้จะซ่อนการดรอปดาวน์และ carets ของมันหากมันเล็กกว่าแท็บเล็ต

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

ทำไมคุณต้องการซ่อนมัน ขณะนี้ผู้ใช้อุปกรณ์พกพาไม่มีทางเข้าถึงลิงก์ที่อยู่ในเมนูย่อย เป็นการดีกว่าที่จะปิดเอฟเฟ็กต์โฮเวอร์บนอุปกรณ์มือถือและทำให้เมนูแบบเลื่อนลงยังคงสภาพเดิม วิธีที่พวกเขาสามารถเปิดได้โดยคลิกที่มัน
พอล

3

โซลูชัน 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;
    }
}

3

ทางออกที่ง่ายมากสำหรับรุ่น 2 เพียง CSS ใช้งานฟังก์ชั่นที่เป็นมิตรเหมือนกันสำหรับมือถือและแท็บเล็ต

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

สิ่งนี้ไม่ได้ผลดีสำหรับบางธีมที่มีช่องว่างระหว่างรายการเมนูและเมนูดร็อปดาวน์ เมนูจะหายไปเมื่อเลื่อนเมาส์ไปที่ช่องว่างนี้
ndbroadbent

2

เขียนทับ bootstrap.js ด้วยสคริปต์นี้

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

นี่คือเทคนิคของฉันที่เพิ่มความล่าช้าเล็กน้อยก่อนที่เมนูจะปิดหลังจากที่คุณหยุดลอยอยู่บนเมนูหรือปุ่มสลับ <button>ที่คุณมักจะคลิกเพื่อแสดงเมนู nav #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

เพื่อปรับปรุงคำตอบของ Sudharshanฉันจะใส่คำสั่งนี้ลงในเคียวรีสื่อบันทึกเพื่อป้องกันการโฮเวอร์เมื่อบนความกว้างของการแสดงผล XS ...

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

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

นอกจากนี้ยังมีรูปหมวกในมาร์กอัปที่ไม่จำเป็นต้องใช้เพียงแบบเลื่อนชั้นสำหรับli



2

ดังนั้นคุณมีรหัสนี้:

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

โดยปกติจะใช้งานได้กับเหตุการณ์การคลิกและคุณต้องการให้มันทำงานกับเหตุการณ์การโฮเวอร์ ง่ายมากเพียงใช้โค้ด JavaScript / jQuery นี้:

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

มันใช้งานได้ดีมากและนี่คือคำอธิบาย: เรามีปุ่มและเมนู เมื่อเราเลื่อนปุ่มเราจะแสดงเมนูและเมื่อเราเลื่อนปุ่มออกไปเราจะซ่อนเมนูหลังจาก 100 ms หากคุณสงสัยว่าทำไมฉันถึงใช้มันเป็นเพราะคุณต้องการเวลาลากเคอร์เซอร์จากปุ่มบนเมนู เมื่อคุณอยู่ในเมนูเวลาจะถูกรีเซ็ตและคุณสามารถอยู่ได้นานเท่าที่คุณต้องการ เมื่อคุณออกจากเมนูเราจะซ่อนเมนูทันทีโดยไม่ต้องหยุดพัก

ฉันใช้รหัสนี้ในหลายโครงการหากคุณพบปัญหาในการใช้รหัสนี้โปรดถามฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.