Auto-collapse sidebar upon clicking anywhere on the page

I have a dynamic sidebar that appears when the user clicks on a hamburger button. Here is the layout:

$('#nav-toggle').click(function() {
  if($('#nav-toggle').hasClass('active')){
    $('.menu').animate({
      right: "0px"
    }, 200);
  }else{
    $('.menu').animate({
      right: "-285px"
    }, 200);
  }

});
.menu{
    right:-285px;
    height:100%;
    position: fixed;
    width: 285px;
    z-index: 1;
    background-color: #111111;
}
.menu ul {
  border-top: 1px solid #636366;
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu li {
  border-bottom: 1px solid #636366;
  font-family: 'Open Sans', sans-serif;
  line-height: 45px;
  padding-bottom: 3px;
  padding-left: 20px;
  padding-top: 3px;
}
.menu li a{
    color:white;
}
    <div class="menu">
      <!-- Menu -->
      <ul>
        <li><a href="#">About</a></li>
        <li><a href="#">Blog</a></li>
        <li><a href="#">Help</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
    </div>

In actuality, the menu can be opened by clicking on the #nav-toggle element and closed by clicking on the same element. I would like to give the user the ability to close the menu by clicking anywhere on the page. How can I achieve this? I attempted using e.preventDefault(); in my if statement but it did not work.

Thank you!

Answer №1

If you want to add a toggle effect to your menu using jQuery, I recommend using the toggleClass method along with adding transition: .2s in the CSS for your .menu. Here is a working example:

$('#nav-toggle').click(function(e) {
  e.stopPropagation();
  $(".menu").toggleClass('bar')
});
$('body').click(function(e) {
  if ($('.menu').hasClass('bar')) {
    $(".menu").toggleClass('bar')
  }
})
.menu {
  right: -285px;
  height: 100%;
  position: fixed;
  width: 285px;
  z-index: 1;
  background-color: #111111;
  transition: .2s
}

.menu ul {
  border-top: 1px solid #636366;
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu li {
  border-bottom: 1px solid #636366;
  font-family: 'Open Sans', sans-serif;
  line-height: 45px;
  padding-bottom: 3px;
  padding-left: 20px;
  padding-top: 3px;
}

.menu li a {
  color: white;
}

.bar {
  right: 0px;
}

body,
html {
  height: 100%;
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="nav-toggle">Click me</button>
<div class="menu">
  <!-- Menu -->
  <ul>
    <li><a href="#">About</a></li>
    <li><a href="#">Blog</a></li>
    <li><a href="#">Help</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</div>

Answer №2

Give this a shot, it will consistently remain hidden when the user clicks anywhere on the body

$(document).on('click',function(){
     if($("#nav-toggle").hasClass("active")){
          $('.menu').animate({ right: "-100%" }, 200);
      }
});

Answer №3

One way to incorporate a parent section into your webpage is by linking a click event similar to what you did with #nav-toggle. Here's an example:

$('.parent-section').click(function() {
 if($('#nav-toggle').hasClass('active')){
  $('.menu').animate({
   right: "0px"
  }, 200);
 } else {
  $('.menu').animate({
   right: "-285px"
  }, 200);
 }

});

Alternatively, you can directly add this functionality to the body tag. However, it is recommended to utilize a section instead of the body for better organization. Hopefully, this solution will be beneficial to you :)

Answer №4

I made a few adjustments to your code :

Take a look :

$('#nav-toggle').click(function(e) {
    e.stopPropagation();
$('.menu').animate({right: "0px"}, 200);
});
$(document).click(function(e){
    $('.menu').animate({right: "-285px"}, 200);
});

Check it out here on JSFiddle

Answer №5

Expanding on Gintoki's response

$('#nav-toggle').on('click', function(e) {

  e.stopPropagation();

  $(".menu").toggleClass('bar');

  $('body').one('click', function(e) {

   if ($('.menu').hasClass('bar')) {
     $(".menu").toggleClass('bar')
   }

  });

});

By removing the listener from body, it ensures that the code does not execute every time.

I'm uncertain about what would be more efficient for performance, but I have reservations about having every click on the website processed through that "if(hasClass)" condition.

Answer №6

$('#nav-toggle').click(function(e) {
  e.stopPropagation();
  $(".menu").toggleClass('bar')
});
$('body').click(function(e) {
  if ($('.menu').hasClass('bar')) {
    $(".menu").toggleClass('bar')
  }
})
.menu {
  right: -285px;
  height: 100%;
  position: fixed;
  width: 285px;
  z-index: 1;
  background-color: #111111;
  transition: .2s
}

.menu ul {
  border-top: 1px solid #636366;
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu li {
  border-bottom: 1px solid #636366;
  font-family: 'Open Sans', sans-serif;
  line-height: 45px;
  padding-bottom: 3px;
  padding-left: 20px;
  padding-top: 3px;
}

.menu li a {
  color: white;
}

.bar {
  right: 0px;
}

body,
html {
  height: 100%;
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="nav-toggle">Click me</button>
<div class="menu">
  <!-- Menu -->
  <ul>
    <li><a href="#">About</a></li>
    <li><a href="#">Blog</a></li>
    <li><a href="#">Help</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Label text facing positioning difficulties

Hey there! I have a goal in mind: https://i.stack.imgur.com/bnso9.png This is what I currently have: http://codepen.io/KieranRigby/pen/QyWZxV. Make sure to view it in "Full page" mode. label { color: #6d6e70; bottom: 0; } .img-row img { width: 10 ...

How can I retrieve the attribute value in a JSP request using jQuery AJAX?

On my website, I have a servlet page and a JSP page. JSP: $.ajax({ url: window.location.href + "?b=b", success:function(data){ //doSomething(data); console.info('$ ...

Applying position: absolute in HTML/CSS to lock parent and child elements in

Transform the boxes into concentric circles (circles within each other that share the same center). The outer circle should be black with a size of 300px and the inner circle should be white with a size of 200px. html: <div id="p10"> <div id ...

"Pushing elements into an array does not function properly within a promise

I'm having trouble with my code - the push method isn't working and it's not returning anything. import {nearbyUsers, getLatitude, getLongitude} from './helper' const users = [] nearbyUsers(session, getLatitude(), getLongitude()).t ...

The Ajax request fails to pass the value to the controller

I've spent the entire day debugging this method and I'm in need of some assistance. My goal is to make an API request and for each array it returns, I want to send a post request to my controller method. However, despite console.log showing the c ...

Having trouble with accessing an element that contains both onclick and text attributes in Selenium Webdriver?

The HTML code I'm dealing with includes this element: <a style="text-decoration:none; font-weight:normal;" href="javascript:void(0);" onclick="CreateNewServiceItemApproved();"> <img src="icons/ui/addnew.png"> <span style="color:# ...

The process of implementing server-side rendering for React Next applications with Material-ui using CSS

I have developed a basic React application using Next.js with an integrated express server: app.prepare() .then(() => { const server = express() server.get('/job/:id', (req, res) => { const actualPage = '/job' const ...

Substituting Div containers with elements imported from external files

Imagine I have <div> <div id="stuff"> <!-- stuff --> </div> </div> Could I move the content of <div id="stuff"> into a separate file named stuff.html, and then replace the code above with something simi ...

What's the solution for aligning these progress bars side by side if floating them doesn't produce the desired result?

I am looking to place two progress bars next to each other, but I have tried using float: left and inline-block without success. I am open to a solution using flex, but I believe there must be a simple fix for this issue. Here is a link to the fiddle for ...

Backstretch.js experiencing issues with element functionality, but functioning correctly with body element

I'm having trouble getting backstretch to work on a div. It works perfectly when applied to the body with no errors, but when I try to apply it to a <div>, I get this error: Uncaught TypeError: Object [object Object] has no method 'backs ...

Maintaining the original layout upon refreshing the page

Incorporating two forms on my website, I added a button that transitions between the login and sign-up forms smoothly. The process is as follows: Initially, the login form is displayed; clicking the button switches to the sign-up form. Proceeding to subm ...

"Need to refresh localStorage in VueJS after navigating back with this.$router.go(-1)? Here's how

Below is my Login.vue code: mounted() { if (localStorage.login) this.$router.go(-1); }, methods: { axios.post(ApiUrl + "/login") { ... } then(response => { ... localStorage.login = true; this.$router.go(0); ...

Position the Bootstrap icon to float to the far right

My icon is always positioned to the right instead of beside the input field. Take a look at the image below: https://i.stack.imgur.com/Bb1eH.png The icon does not align next to the input field. This is my code snippet : <div class="form-horizontal"& ...

What is the best way to enable a DOM element's height to be resized?

I have a widget displayed in the corner of my browser that I would like to make resizable by dragging the header upwards to increase its height. The widget's position remains fixed with its bottom, left, and right properties unchanged, but I need the ...

Incorporating Material-UI with React Searchkit for a seamless user experience, featuring

I encountered an issue when trying to use both searchkit and material-ui in my React application. The problem arises from the fact that these two libraries require different versions of reactjs. Initially, everything was working fine with just searchkit in ...

What is the best way to fetch images from a JSON object in a React application?

I have been trying to load images from an array of objects in React, but I keep encountering a "module not found" error. This issue has been frustrating me for the past couple of days. Can someone please help me troubleshoot this problem or provide some su ...

Encountering a surprising token error while running a node.js application with a classic example

I downloaded node.js from its official website and followed the instructions provided here. I attempted to run the example code snippet from the "JavaScript - The Good Parts" textbook: var myObject = { value: 0; increment: function (inc) { this.value ...

Avoid cascading of the 'display' property in JavaScript styling to prevent inheritance

Is there a way in Javascript to toggle the visibility of a larger portion of HTML without affecting inner display properties with display: <value>? Despite setting an outer display property using Javascript, the inner display properties are also alt ...

Struggling to properly align a div on top of an image

view image description herei need assistance with centering the div over the background image. I attempted to use relative positioning for the container and absolute positioning for the elements, but it did not yield the desired result. The code snippet be ...

The result of Document.getElementById can show as "undefined" despite the presence of the element

Currently, I am tackling a project that involves extracting information from a website. I have opted to use the 'puppeteer' library in Node.Js for this task. However, I am encountering an issue where Document.getElementById is returning "undefine ...