问题
I'm using the offcanvas experiment code from Bootstrap 4 documentation, but it's not designed to close when you click outside the menu, which is something I would really like it to do.
I've tried several of the jquery snippets around the web, but they utilize bootstrap's .collapse and don't work when I edit them to contain the custom .offcanvas-collapse class.
<nav class="navbar fixed-top navbar-dark bg-dark">
<button class="navbar-toggler p-0 border-0" type="button" data-toggle="offcanvas" data-target="#offcanvasNav" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<i data-feather="menu"></i>
</button>
<a class="navbar-brand" href="#">Sleight of Word</a>
<button class="navbar-toggler p-0 border-0" type="button" data-toggle="searchBar">
<i data-feather="search"></i>
</button>
<form class="form-inline my-2 my-lg-0 d-none">
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
<div class="navbar-collapse offcanvas-collapse" id="offcanvasNav">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Dashboard <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Notifications</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Switch account</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Settings</a>
<div class="dropdown-menu" aria-labelledby="dropdown01">
<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" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
.offcanvas-collapse {
position: fixed;
top: 56px; /* Height of navbar */
bottom: 0;
right: 100%;
width: 240px;
padding-right: 1rem;
padding-left: 1rem;
overflow-y: auto;
visibility: hidden;
background-color: purple;
transition: visibility .2s ease-in-out, -webkit-transform .2s ease-in-out;
transition: transform .2s ease-in-out, visibility .2s ease-in-out;
transition: transform .2s ease-in-out, visibility .2s ease-in-out, -webkit-transform .2s ease-in-out;
}
.offcanvas-collapse.open {
visibility: visible;
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
$(function () {
'use strict'
$('[data-toggle="offcanvas"]').on('click', function () {
$('.offcanvas-collapse').toggleClass('open')
})
})
$(document).on('click',function(){
$('.offcanvas-collapse').offcanvas-collapse('hide');
})
I was hoping that this would make the offcanvas nav toggleable (open and close) with the menu button and make the nav close when click outside the menu, but clicking outside the nav does nothing.
回答1:
$(document).on('click',function(){
$('.offcanvas-collapse').toggleClass('open');
})
alone, will toggle the class open
on all elements having the class offcanvas-collapse
in your document. If the element has the class, it will be removed, otherwise it will be added.
If you combine the above with the other snippet:
$(function () {
'use strict'
$('[data-toggle="offcanvas"]').on('click', function () {
$('.offcanvas-collapse').toggleClass('open')
})
})
..., every time you click on [data-toggle="offcanvas"]
, both snippets are running (because you click on [data-toggle="offcanvas"]
but you also click on document
(because click
event bubbles all the way up to document
, unless prevented). Therefore the class offcanvas-collapse
gets toggled twice, so it will look like it's not working.
That's clearly not what you're after.
You probably want to:
- toggle the class
open
on.offcanvas-collapse
elements when[data-toggle="offcanvas"]
is clicked without allowing thatclick
event to propagate todocument
. - remove (not toggle) the class
open
from.offcanvas-collapse
elements when a click is performed anywhere in the document. If you usetoggle
, aclick
indocument
when offcanvas is closed will open it, which is probably not what you want.
That being said, here's the practical way to do it:
$(function () {
'use strict'
$(document)
.on('click', '[data-toggle="offcanvas"]', function(e) {
$('.offcanvas-collapse').toggleClass('open'); // toggle `.open`
e.stopPropagation(); // and stop propagation
})
.on('click', function() {
$('.offcanvas-collapse').removeClass('open'); // remove `.open`
});
})
Edit: as per the comment request, to only close the off-canvas when clicking outside of the navbar, replace the second .on()
with this one:
.on('click', function(e) {
if (!$(e.target).closest('nav.fixed-top').is('nav')) {
$('.offcanvas-collapse').removeClass('open'); // remove `.open`
}
});
It check is the target clicked is inside a <nav>
with class fixed-top
.
来源:https://stackoverflow.com/questions/57259093/how-do-i-outside-click-to-close-this-custom-offcanvas-nav-from-bootstraps-docs