Reputation: 569
Even after reading about 20 related questions/threads on here I just cannot figure this out, been trying things for hours but just cant get it, so really hoping someone can put me out of my misery!
I have a slide out menu that currently requires the user to click on the "X" to close it, I need to make it possible for users to click anywhere outside of the menu OR on the "X" to close it.
Ive created a codepen to make it easier to look at the code as theres quite a lot of it.
jQuery(document).ready(function($){
$('.btn-open-menu').click(function () {
$('header').addClass('open');
$('html').addClass('open');
$('html, body').addClass('noscroll');
});
$('.link-menu').click(function () {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
$('.btn-close-menu').click(function () {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
$('.btn-open-menu2').click(function () {
$('header').addClass('open');
$('html').addClass('open');
$('html, body').addClass('noscroll');
});
$('.link-menu').click(function () {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
$('.btn-close-menu2').click(function () {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
});
header {
width: 100%;
background-color: transparent;
position: fixed;
top: 0;
left: 0;
z-index: 10;
transition: 0.5s ease-in-out;
}
header .btn-open-menu {
width: 25px;
height: 25px;
position: absolute;
top: 50px;
right: 50px;
cursor: pointer;
}
@media only screen and (max-width: 767px) {
header .btn-open-menu {
top: 25px;
right: 20px;
}
}
@media only screen and (max-width: 767px) {
header .header-content {
width: 100% !important;
}
}
header .header-content {
width: 30%;
height: 100vh;
height: calc(var(--vh, 1vh) * 100);
background-color: #FB4D98;
box-sizing: border-box;
position: absolute;
top: 0;
left:initial; right: -100%;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
flex-direction: column;
align-content: center;
transition: 0.8s ease-in-out;
}
@media only screen and (max-width: 767px) {
header .header-content .btn-close-menu {
top: 20px !important;
right: 20px !important;
}
}
header .header-content .btn-close-menu {
width: 25px;
height: 25px;
position: absolute;
top: 50px;
right: 50px;
cursor: pointer;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
flex-direction: row;
align-content: center;
}
header .header-content .btn-close-menu:before, header .header-content .btn-close-menu:after {
background: #F4FB82;
content: '';
display: block;
width: 100%;
height: 4px;
position: absolute;
transition: 0.5s ease-in-out;
}
header .header-content .btn-close-menu:before {
transform: rotate(45deg);
}
header .header-content .btn-close-menu:hover{
transform: rotate(180deg);
transition:0.5s ease-in-out;
}
header .header-content .btn-close-menu:after {
transform: rotate(-45deg);
}
header .header-content nav {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
flex-direction: column;
align-content: center;
}
header .header-content nav a {
color: #000;
letter-spacing: 0.5px;
line-height: 35px;
text-decoration: none;
transition: 0.5s;
}
header .header-content nav a:hover {
color: rgba(0, 0, 0, 0.5);
transition: 1s;
}
header .header-content .social {
display: flex;
justify-content: center;
align-items: center;
margin: 40px 0 0 0;
font-size: 20px;
}
header .header-content .social a {
color: #000;
text-decoration: none;
margin: 0 10px;
transition: 0.5s;
}
header .header-content .social a:hover {
color: #F4FB82;
transform: scale(1.5);
transition: 0.5s;
}
header.open {
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
transition: 0.5s ease-in-out;
}
header.open .btn-open-menu, header.open .logo {
opacity: 0;
transition: 1s ease-in-out;
}
header.open .header-content {
left:initial; right: 0;
transition: 0.8s ease-in-out;
}
.Menu-list {
font-family: "alliance";
font-size: 4vw;
line-height: 1.2;
text-transform: uppercase;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
}
@media only screen and (max-width: 767px) {
.Menu-list {
font-family: "alliance";
font-size: 12vw;
}
}
.Menu-list-item {
position: relative;
color: transparent;
cursor: pointer;
}
ul.Menu-list{
padding-inline-start: 0px !important;
}
.Menu-list-item::before {
content: '';
display: block;
position: absolute;
top: 49%;
left: -10%;
right: -10%;
height: 4px;
border-radius: 4px;
margin-top: -2px;
background: #F4FB82;
transform: scale(0);
z-index: 1;
}
.Mask {
display: block;
position: absolute;
overflow: hidden;
padding-right: 5px;
padding-left: 5px;
color: #F4FB82;
top: 0;
height: 49%;
transition: all 1s cubic-bezier(0.16, 1.08, 0.38, 0.98);
}
@media only screen and (max-width: 767px) {
.Mask {
transition: all 0.2s cubic-bezier(0.16, 1.08, 0.38, 0.98);
}
}
.Mask span {
display: block;
}
.Mask + .Mask {
top: 48.9%;
height: 51.1%;
}
.Mask + .Mask span {
transform: translateY(-49%);
}
.Menu-list-item:hover .Mask, .Menu-list-item:active .Mask {
color: #000;
transform: skewX(12deg) translateX(5px);
}
.Menu-list-item:hover .Mask + .Mask, .Menu-list-item:active .Mask + .Mask {
transform: skewX(12deg) translateX(-5px);
}
.Menu-list-item:hover::before, .Menu-list-item:active::before {
transform: scale(1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<a class="btn-open-menu">
<span class="hamburguer"><img src="https://upload.wikimedia.org/wikipedia/commons/b/b2/Hamburger_icon.svg"></span>
</a>
<div class="header-content">
<a class="btn-close-menu"></a>
<nav>
<div class="Menu">
<ul class="Menu-list" data-offset="10">
<li class="Menu-list-item" data-offset="20" onclick="location.href='/home';">
Home
<span class="Mask"><span>Home</span></span>
<span class="Mask"><span>Home</span></span>
</li>
<li class="Menu-list-item" data-offset="16" onclick="location.href='/about';">
About
<span class="Mask"><span>About</span></span>
<span class="Mask"><span>About</span></span>
</li>
<li class="Menu-list-item" data-offset="12" onclick="location.href='/contact';">
Contact
<span class="Mask"><span>Contact</span></span>
<span class="Mask"><span>Contact</span></span>
</li>
</ul>
</div>
</nav>
</header>
Upvotes: 2
Views: 3687
Reputation: 30993
You can simplify this by using stopPropagation
in your open click handler, and close the menu in a generic click header
handler.
$('.btn-open-menu').click(function (e) {
$('header').addClass('open');
$('html').addClass('open');
$('html, body').addClass('noscroll');
e.stopPropagation();
});
You can let the menu open, by clicking on the background using:
$(".header-content").click(function (e) {
e.stopPropagation();
});
Ref: https://api.jquery.com/event.stoppropagation/
Upvotes: 2
Reputation: 383
A better way to do it is creating an overlay element behind the header and hide it and the menu when it is clicked.
jQuery(document).ready(function($){
$('.btn-open-menu').click(function () {
$('header').addClass('open');
$('html').addClass('open');
$('html, body').addClass('noscroll');
});
$('.link-menu').click(function () {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
$('.btn-close-menu').click(function () {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
$('.btn-open-menu2').click(function () {
$('header').addClass('open');
$('html').addClass('open');
$('html, body').addClass('noscroll');
});
$('.link-menu').click(function () {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
$('.btn-close-menu2').click(function () {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
$('.overlay').click(function () {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
});
header {
width: 100%;
background-color: transparent;
position: fixed;
top: 0;
left: 0;
z-index: 10;
transition: 0.5s ease-in-out;
}
header .btn-open-menu {
width: 25px;
height: 25px;
position: absolute;
top: 50px;
right: 50px;
cursor: pointer;
}
@media only screen and (max-width: 767px) {
header .btn-open-menu {
top: 25px;
right: 20px;
}
}
@media only screen and (max-width: 767px) {
header .header-content {
width: 100% !important;
}
}
header .header-content {
width: 30%;
height: 100vh;
height: calc(var(--vh, 1vh) * 100);
background-color: #FB4D98;
box-sizing: border-box;
position: absolute;
top: 0;
left:initial; right: -100%;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
flex-direction: column;
align-content: center;
transition: 0.8s ease-in-out;
}
@media only screen and (max-width: 767px) {
header .header-content .btn-close-menu {
top: 20px !important;
right: 20px !important;
}
}
header .header-content .btn-close-menu {
width: 25px;
height: 25px;
position: absolute;
top: 50px;
right: 50px;
cursor: pointer;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
flex-direction: row;
align-content: center;
}
header .header-content .btn-close-menu:before, header .header-content .btn-close-menu:after {
background: #F4FB82;
content: '';
display: block;
width: 100%;
height: 4px;
position: absolute;
transition: 0.5s ease-in-out;
}
header .header-content .btn-close-menu:before {
transform: rotate(45deg);
}
header .header-content .btn-close-menu:hover{
transform: rotate(180deg);
transition:0.5s ease-in-out;
}
header .header-content .btn-close-menu:after {
transform: rotate(-45deg);
}
header .header-content nav {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
flex-direction: column;
align-content: center;
}
header .header-content nav a {
color: #000;
letter-spacing: 0.5px;
line-height: 35px;
text-decoration: none;
transition: 0.5s;
}
header .header-content nav a:hover {
color: rgba(0, 0, 0, 0.5);
transition: 1s;
}
header .header-content .social {
display: flex;
justify-content: center;
align-items: center;
margin: 40px 0 0 0;
font-size: 20px;
}
header .header-content .social a {
color: #000;
text-decoration: none;
margin: 0 10px;
transition: 0.5s;
}
header .header-content .social a:hover {
color: #F4FB82;
transform: scale(1.5);
transition: 0.5s;
}
header.open .overlay{
position:fixed;
width:100vW;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
transition: 0.5s ease-in-out;
}
header.open .btn-open-menu, header.open .logo {
opacity: 0;
transition: 1s ease-in-out;
}
header.open .header-content {
left:initial; right: 0;
transition: 0.8s ease-in-out;
}
.Menu-list {
font-family: "alliance";
font-size: 4vw;
line-height: 1.2;
text-transform: uppercase;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
}
@media only screen and (max-width: 767px) {
.Menu-list {
font-family: "alliance";
font-size: 12vw;
}
}
.Menu-list-item {
position: relative;
color: transparent;
cursor: pointer;
}
ul.Menu-list{
padding-inline-start: 0px !important;
}
.Menu-list-item::before {
content: '';
display: block;
position: absolute;
top: 49%;
left: -10%;
right: -10%;
height: 4px;
border-radius: 4px;
margin-top: -2px;
background: #F4FB82;
transform: scale(0);
z-index: 1;
}
.Mask {
display: block;
position: absolute;
overflow: hidden;
padding-right: 5px;
padding-left: 5px;
color: #F4FB82;
top: 0;
height: 49%;
transition: all 1s cubic-bezier(0.16, 1.08, 0.38, 0.98);
}
@media only screen and (max-width: 767px) {
.Mask {
transition: all 0.2s cubic-bezier(0.16, 1.08, 0.38, 0.98);
}
}
.Mask span {
display: block;
}
.Mask + .Mask {
top: 48.9%;
height: 51.1%;
}
.Mask + .Mask span {
transform: translateY(-49%);
}
.Menu-list-item:hover .Mask, .Menu-list-item:active .Mask {
color: #000;
transform: skewX(12deg) translateX(5px);
}
.Menu-list-item:hover .Mask + .Mask, .Menu-list-item:active .Mask + .Mask {
transform: skewX(12deg) translateX(-5px);
}
.Menu-list-item:hover::before, .Menu-list-item:active::before {
transform: scale(1);
}
.social {
position: fixed;
bottom: 60px;
}
.copyright {
position: fixed;
bottom: 40px;
font-family: "alliance";
font-size: 14px;
color: #0E0E0E;
white-space: nowrap;
}
.privacy-policy {
position: fixed;
bottom: 20px;
font-family: "alliance";
font-size: 8px;
color: #0E0E0E !important;
white-space: nowrap;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<div class="overlay"></div>
<a class="btn-open-menu">
<span class="hamburguer"><img src="https://upload.wikimedia.org/wikipedia/commons/b/b2/Hamburger_icon.svg"></span>
</a>
<div class="header-content">
<a class="btn-close-menu"></a>
<nav>
<div class="Menu">
<ul class="Menu-list" data-offset="10">
<li class="Menu-list-item" data-offset="20" onclick="location.href='/home';">
Home
<span class="Mask"><span>Home</span></span>
<span class="Mask"><span>Home</span></span>
</li>
<li class="Menu-list-item" data-offset="16" onclick="location.href='/about';">
About
<span class="Mask"><span>About</span></span>
<span class="Mask"><span>About</span></span>
</li>
<li class="Menu-list-item" data-offset="12" onclick="location.href='/contact';">
Contact
<span class="Mask"><span>Contact</span></span>
<span class="Mask"><span>Contact</span></span>
</li>
</ul>
</div>
</nav>
</header>
Upvotes: 2
Reputation: 1023
You can try this one. The one that you were missing is stopPropagation()
jQuery(document).ready(function($){
$('.btn-open-menu').click(function (e) {
e.stopPropagation();
$('header').addClass('open');
$('html').addClass('open');
$('html, body').addClass('noscroll');
});
$('.link-menu').click(function () {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
$('.btn-close-menu').click(function (e) {
e.stopPropagation();
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
$('.btn-open-menu2').click(function () {
$('header').addClass('open');
$('html').addClass('open');
$('html, body').addClass('noscroll');
});
$('.link-menu').click(function () {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
$('.btn-close-menu2').click(function () {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
$(document).click(function() {
$('header').removeClass('open');
$('html').removeClass('open');
$('html, body').removeClass('noscroll');
});
});
header {
width: 100%;
background-color: transparent;
position: fixed;
top: 0;
left: 0;
z-index: 10;
transition: 0.5s ease-in-out;
}
header .btn-open-menu {
width: 25px;
height: 25px;
position: absolute;
top: 50px;
right: 50px;
cursor: pointer;
}
@media only screen and (max-width: 767px) {
header .btn-open-menu {
top: 25px;
right: 20px;
}
}
@media only screen and (max-width: 767px) {
header .header-content {
width: 100% !important;
}
}
header .header-content {
width: 30%;
height: 100vh;
height: calc(var(--vh, 1vh) * 100);
background-color: #FB4D98;
box-sizing: border-box;
position: absolute;
top: 0;
left:initial; right: -100%;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
flex-direction: column;
align-content: center;
transition: 0.8s ease-in-out;
}
@media only screen and (max-width: 767px) {
header .header-content .btn-close-menu {
top: 20px !important;
right: 20px !important;
}
}
header .header-content .btn-close-menu {
width: 25px;
height: 25px;
position: absolute;
top: 50px;
right: 50px;
cursor: pointer;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
flex-direction: row;
align-content: center;
}
header .header-content .btn-close-menu:before, header .header-content .btn-close-menu:after {
background: #F4FB82;
content: '';
display: block;
width: 100%;
height: 4px;
position: absolute;
transition: 0.5s ease-in-out;
}
header .header-content .btn-close-menu:before {
transform: rotate(45deg);
}
header .header-content .btn-close-menu:hover{
transform: rotate(180deg);
transition:0.5s ease-in-out;
}
header .header-content .btn-close-menu:after {
transform: rotate(-45deg);
}
header .header-content nav {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
flex-direction: column;
align-content: center;
}
header .header-content nav a {
color: #000;
letter-spacing: 0.5px;
line-height: 35px;
text-decoration: none;
transition: 0.5s;
}
header .header-content nav a:hover {
color: rgba(0, 0, 0, 0.5);
transition: 1s;
}
header .header-content .social {
display: flex;
justify-content: center;
align-items: center;
margin: 40px 0 0 0;
font-size: 20px;
}
header .header-content .social a {
color: #000;
text-decoration: none;
margin: 0 10px;
transition: 0.5s;
}
header .header-content .social a:hover {
color: #F4FB82;
transform: scale(1.5);
transition: 0.5s;
}
header.open {
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
transition: 0.5s ease-in-out;
}
header.open .btn-open-menu, header.open .logo {
opacity: 0;
transition: 1s ease-in-out;
}
header.open .header-content {
left:initial; right: 0;
transition: 0.8s ease-in-out;
}
.Menu-list {
font-family: "alliance";
font-size: 4vw;
line-height: 1.2;
text-transform: uppercase;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
}
@media only screen and (max-width: 767px) {
.Menu-list {
font-family: "alliance";
font-size: 12vw;
}
}
.Menu-list-item {
position: relative;
color: transparent;
cursor: pointer;
}
ul.Menu-list{
padding-inline-start: 0px !important;
}
.Menu-list-item::before {
content: '';
display: block;
position: absolute;
top: 49%;
left: -10%;
right: -10%;
height: 4px;
border-radius: 4px;
margin-top: -2px;
background: #F4FB82;
transform: scale(0);
z-index: 1;
}
.Mask {
display: block;
position: absolute;
overflow: hidden;
padding-right: 5px;
padding-left: 5px;
color: #F4FB82;
top: 0;
height: 49%;
transition: all 1s cubic-bezier(0.16, 1.08, 0.38, 0.98);
}
@media only screen and (max-width: 767px) {
.Mask {
transition: all 0.2s cubic-bezier(0.16, 1.08, 0.38, 0.98);
}
}
.Mask span {
display: block;
}
.Mask + .Mask {
top: 48.9%;
height: 51.1%;
}
.Mask + .Mask span {
transform: translateY(-49%);
}
.Menu-list-item:hover .Mask, .Menu-list-item:active .Mask {
color: #000;
transform: skewX(12deg) translateX(5px);
}
.Menu-list-item:hover .Mask + .Mask, .Menu-list-item:active .Mask + .Mask {
transform: skewX(12deg) translateX(-5px);
}
.Menu-list-item:hover::before, .Menu-list-item:active::before {
transform: scale(1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<a class="btn-open-menu">
<span class="hamburguer"><img src="https://upload.wikimedia.org/wikipedia/commons/b/b2/Hamburger_icon.svg"></span>
</a>
<div class="header-content">
<a class="btn-close-menu"></a>
<nav>
<div class="Menu">
<ul class="Menu-list" data-offset="10">
<li class="Menu-list-item" data-offset="20" onclick="location.href='/home';">
Home
<span class="Mask"><span>Home</span></span>
<span class="Mask"><span>Home</span></span>
</li>
<li class="Menu-list-item" data-offset="16" onclick="location.href='/about';">
About
<span class="Mask"><span>About</span></span>
<span class="Mask"><span>About</span></span>
</li>
<li class="Menu-list-item" data-offset="12" onclick="location.href='/contact';">
Contact
<span class="Mask"><span>Contact</span></span>
<span class="Mask"><span>Contact</span></span>
</li>
</ul>
</div>
</nav>
</div>
</header>
Upvotes: 0
Reputation:
You can add an event listener to the window itself so it closes anywhere you click.
window.addEventListener('click', (e) => {
if (e.target !== document.getElementById('dropdown')) {
// remove class here
}
})
// (e.target as HTMLElement) if you're using typescript
Sometimes that can be problematic if you're clicking on an item inside the dropdown and it still closes because of the immediate element not being the dropdown itself. You can fix that using contains
.
window.addEventListener('click', (e) => {
const dropdown = document.getElementByid('dropdown')
const item = document.getElementsByClass('dropdownItem')[0]
if (e.target !== dropdown && !e.target.contains(item)) {
// remove class here
}
})
Upvotes: 1