简体   繁体   中英

Bootstrap 4 - Keeping Parent of Dropdown a clickable link

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">Navbar</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Link</a>
      </li>
      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
          Dropdown
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdown">
          <a class="dropdown-item" href="#">Action</a>
          <a class="dropdown-item" href="#">Another action</a>
          <div class="dropdown-divider"></div>
          <a class="dropdown-item" href="#">Something else here</a>
        </div>
      </li>
      <li class="nav-item">
        <a class="nav-link disabled" href="#">Disabled</a>
      </li>
    </ul>
    <form class="form-inline my-2 my-lg-0">
      <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
      <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
    </form>
  </div>
</nav>

New to bootstrap. Here's the code based on the Bootstrap example. Right now the dropdown shows up but you're not able to click on the dropdown itself. I want to be able to make all the parent nav links work. Similar to this website: https://eastcfashion.com/

Where clicking on for example: men's collection brings you to all the collection for that area. But the dropdown menu, you're able to just go on specific items.

I'm trying to implement it in a way that the main parent nav would say Projects. and the dropdown menu for projects would show specific pages for each project like project 1, project 2, etc. But clicking on Projects would take you to a page where project 1, project 2, and the collection of projects would be showing as a group and not individually.

 jQuery(function($) { if ($(window).width() > 769) { $('.navbar .dropdown').hover(function() { $(this).find('.dropdown-menu').first().stop(true, true).delay(250).slideDown(); }, function() { $(this).find('.dropdown-menu').first().stop(true, true).delay(100).slideUp(); }); $('.navbar .dropdown > a').click(function() { location.href = this.href; }); } });
 @media only screen and (min-width:769px) { .dropdown:hover .dropdown-menu { display: block; } .dropdown-submenu { position: relative !important; } .dropdown-submenu>.dropdown-menu { top: 0 !important; left: 100% !important; margin-top: -6px !important; margin-left: -1px !important; border-radius: 0 !important; } .dropdown-submenu:hover>.dropdown-menu { display: block !important; } .dropdown-submenu>a:after { display: block; content: "\\f105"; font-family: 'FontAwesome'; margin-top: -18px; right: 15px; position: absolute; font-weight: 300; } }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://v4-alpha.getbootstrap.com/dist/js/bootstrap.min.js"></script> <link href="https://v4-alpha.getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet" /> <nav class="navbar navbar-toggleable-md navbar-light bg-faded"> <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <a class="navbar-brand" href="#">Navbar</a> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li><li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="http://example.com" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Dropdown link </a> <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> </div> </li> </ul> <form class="form-inline my-2 my-lg-0"> <input class="form-control mr-sm-2" type="text" placeholder="Search"> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> </form> </div> </nav>

The easiest way to do it is by deleting the "data-toggle" attribute from the parent element! edit: thx for the tip, here is a code example: I changed this:

<a class="p-2 text-dark dropdown-toggle" data-toggle="dropdown" style="font-size:1.25rem;" href= {% url 'link' %}>Link</a>

to this:

<a class="p-2 text-dark dropdown-toggle" style="font-size:1.25rem;" href= {% url 'link' %}>Link</a>

so, in essence, I simply deleted the data toggle attribute and thus converted a hoverable dropdown into a hoverable dropdown with a clickable parent link.

I tried to keep the code simple. My solution is to detect the second click on the dropdown button/link and follow the link at that point.

$('.navbar .dropdown > a').click(function() {
 if (!$(this).hasClass("parent-clicked")) {
    $(this).addClass("parent-clicked");
  } else {
    location.href = this.href;
  }
});

This works in the collapsed view as well.

I took Joe's answer and improved it to my needs

/*
 * Only go to the link when dropdown is already open (if the dropdown is a link)
 */
$('.navbar ul.navbar-nav > .dropdown > a[href]').click(function() {
    var dropdown = $(this).next('.dropdown-menu');
    /*
     * The dropdown can be non-existent
     * The dropdown can be already open by css
     * (for instance display: block from a custom :hover setting) 
     * or a "show" class on the element which also sets a display: block;
     */
    if (dropdown.length == 0 || $(dropdown).css('display') !== 'none') {
        if (this.href) {
            location.href = this.href;
        }
    }
});

The Bootstrap 4 html for this is

<header class="navbar"> 
    <ul class="nav navbar-nav">            
        <li class="nav-item dropdown">
            <a class="nav-link" href="/planning" data-toggle="dropdown">
                Planning
            </a>
            <ul class="dropdown-menu">
                <li class="dropdown-item">
                    <a href="/day-planning">Day planning</a>
                </li>
            </ul>
        </li>
    </ul>
</header>

Clickable dropdown link in Bootstrap 4

I hide the original dropdown triangle icon and make a new plus icon because the original icon is very small and made with pseudo-class :after , it's hard for user to point the cursor and click it.

So the parent href link will work as normal but when user click on plus icon it will open the dropdown.

 /* ----------------------------------------------------------------------- Make Bootstrap dropdown "a" link clickable But when clicking plus icon, show the dropdown --------------------------------------------------------------------------- */ function clickableDropdownLink() { if (window.matchMedia("(max-width: 992px)").matches) { const dropdownToggle = $('.navbar .dropdown > a'); dropdownToggle.append('<span class="dropdown-icon"></span>'); dropdownToggle.removeAttr('data-toggle'); $('.navbar .dropdown > a').click(function(e) { e.preventDefault(); if ((e.target.tagName == 'A')) { const route = $(this).attr("href"); window.location.href = route == '/' || route == '#' ? window.location.href : route; return; } }) const dropdownIcon = $('.navbar .dropdown > a > span.dropdown-icon'); dropdownIcon.click(function() { const parentLink = $(this).parent("a.nav-link"); parentLink.parent(".nav-item").toggleClass("show"); parentLink.next(".dropdown-menu").toggle(); }) } } clickableDropdownLink(); /* ------------------------------------------------------------------------------------ This is optional, this could make your app slower If you want to make a dropdown link clickable after user resizing screen, you can add this. This could make your app slower ----------------------------------------------------------------------------------------- */ $(window).resize(function() { clickableDropdownLink(); }) /* ------------------------------------------------------------------------------------ This is optional If you also want the dropdown link work in Desktop size. ----------------------------------------------------------------------------------------- */ if (window.matchMedia("(min-width: 992px)").matches) { $('.navbar .dropdown > a').click(function() { location.href = this.href; }); }
 .dropdown .dropdown-icon{ display: none; position: absolute; padding: 15px; background: #fff; right: 10px; top: 8px; } .dropdown .dropdown-icon:before{ transition: all ease 0.5s; background: #444; height: 2px; width: 16px; top: 14px; left: 7px; content: ""; position: absolute; } .dropdown .dropdown-icon:after{ transition: all ease 0.5s; background: #444; content: ""; height: 16px; left: 14px; position: absolute; top: 7px; width: 2px; } .dropdown.show .dropdown-icon:after{ transform:rotate(-90deg); } .dropdown.show .dropdown-icon:before{ transform:rotate(-180deg); } .navbar .dropdown .dropdown-toggle .dropdown-icon{ display:none; } @media(max-width:992px){ .navbar .dropdown .dropdown-toggle::after{ display:none; } .navbar .dropdown .dropdown-toggle .dropdown-icon{ display:block; } .navbar .dropdown .dropdown-menu .dropdown-item{ white-space:pre-wrap; } }
 <!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <title>Clickable Dropdown Link</title> <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css'><link rel="stylesheet" href="./style.css"> </head> <body> <!-- partial:index.partial.html --> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <a class="navbar-brand" href="#">Navbar</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="https://www.google.com" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Dropdown1 </a> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="#">Action 1</a> <a class="dropdown-item" href="#">Another action 1</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="#">Something else here 1</a> </div> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="https://www.google.com" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Dropdown </a> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="#">Something else here</a> </div> </li> <li class="nav-item"> <a class="nav-link disabled" href="#">Disabled</a> </li> </ul> <form class="form-inline my-2 my-lg-0"> <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search"> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> </form> </div> </nav> <!-- partial --> <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.9.1/umd/popper.min.js'></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js'></script><script src="./script.js"></script> </body> </html>

<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>

This snippet toggles the dropdown but on click event and href is used to toggle the dropdown menu. So According to your need -

Redirect href to the general project page and add hover event to display the dropdown menu using jquery or CSS.To display the Dropdown menu just add open class to <li class="nav-item dropdown">

Using CSS , Using Jquery

Here is my solution. The idea is to detect the area that the user clicked on the dropdown button/link and redirect to that url.

  // clickable dropdown menu parent
  $('.navbar .dropdown > a').on('click', function(e) {
    let elementBegin = $(this).offset()['left']; // get link position X

    // get the width of the menu by text's length
    // you need to contain the text inside a span tag
    let spanWidth = $(this).find("> span").width();
    let clickAreaLength = spanWidth * 0.9; // 90% of width = clickable area

    let clickPositionX = e.pageX; // position of the click

    // if click position is inside the clickable area, then redirect
    if (clickPositionX < elementBegin + clickAreaLength) {
      location.href = this.href;
    }
  });

This works in the collapsed view (mobile) as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM