How can I close menu after click outside menu? - javascript

I want to make hiding sidebar menu which will be opened whenuser click button. After that when user click outside menu - menu will be closed. How can I make this function in this case?
JsFiddle
function openNav() {
document.getElementById("mySidenav").style.width = "250px";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;
}
.sidenav a:hover {
color: #f1f1f1;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
<div id="mySidenav" class="sidenav">
×
About
Services
Clients
Contact
</div>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">☰ open</span>

You can react on a click on the entire document element and find out whether the target is located within your menu:
document.documentElement.addEventListener("click", function(e){
if (e.button != 1) // left mouse
return; // anything else => do nothing
var target = e.target;
var navItem = document.getElementById("mySidenav");
do{
if (target == navItem)
return; // clicked within "mySidenav" => do nothing
target = target.parentNode;
}
while(target != null);
// react here
closeNav(); // must be implemented somewhere
});
It is desirable not to react at all if you detect that the click was indeed fired within your menu because otherwise you might close the menu before the click gets bubbled to the item => no menu item click detected.

function openNav() {
document.getElementById("mySidenav").style.width = "250px";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
}
document.addEventListener('mousedown',function(event){
var side_dom = document.getElementById("mySidenav")
if(side_dom.style.width == '250px'){
if(!side_dom.contains(event.target)){
document.getElementById("mySidenav").style.width = "0";
}
}
})
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;
}
.sidenav a:hover {
color: #f1f1f1;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
<body>
<div id="mySidenav" class="sidenav">
×
About
Services
Clients
Contact
</div>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">☰ open</s
</body>

Related

why doesn't off canvas code work in mobile?

I got this code from https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_sidenav and it works fine in mobile as is. So simple, yet effective. But my usage doesn't work in my mobile or my customer's mobile.
console says:
(index):66 Uncaught TypeError: Cannot read properties of null (reading 'style')
at openNav ((index):66)
at HTMLDivElement.onmouseover ((index):79)
Would anyone like to hazard a guess as to why this doesn't work?
function openNav() {
document.getElementById("mySidenav").style.width = "250px";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #96AD74;
background-color: #9C836E;
overflow-x: hidden;
transition: 0.5s;
padding-top: 30px;
letter-spacing: 1px;
}
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #E2FAC0;
display: block;
transition: 0.3s;
text-shadow: 1px 1px 0 #000;
}
.sidenav a:hover {
color: darkblue;
background: #808000;
background: #7E6EB5;
background: #FFAC1C;
text-shadow: none;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
text-shadow: none;
}
#main {
transition: margin-left .5s;
padding: 16px;
}
#media screen and (max-height: 450px) {
.sidenav {
padding-top: 15px;
}
.sidenav a {
font-size: 18px;
}
<div id="mySidenav" class="sidenav" onmouseleave="closeNav();">
<div class="pcc">MENU</div>
home
coaching
biography
contact
</div>
If I understand correctly, you want to close the menu when the user touches anything outside of it on a phone.
Add the following to your JavaScript file:
document.addEventListener('click', function(e) {
var mySidenav = document.getElementById("mySidenav");
var openButton = document.getElementById("openButton");
if (mySidenav.style.width == "250px" && !mySidenav.contains(e.target) && e.target != openButton) {
closeNav();
}
});
This will make it so when you click (touch) on any element besides the open button, it will close the sidebar.
Also, don't forget to set the ID of the element opening the navbar to "openButton", for example in the W3School tutorial you linked, you should modify it like this:
<span id="openButton" style="font-size:30px;cursor:pointer" onclick="openNav()">☰ open</span>

how to create an auto hide sidebar

I am trying to generate a sidebar which hides automatic by clicking every other things except the sidebar (with js or css).
my code is:
<script>
function openNav() {
document.getElementById("mySidenav").style.width = "250px";
}
</script>
...
<div id="mySidenav" class="sidenav">
About
Services
Clients
Contact
</div>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">☰ open</span>
and css is :
<style>
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;
}
</style>
i used HTML, JavaScript, and CSS
thanks
Try below solution.
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;
}
<script>
function openNav() {
document.getElementById("mySidenav").style.width = "250px";
}
window.addEventListener('click', function(e){
if (!document.getElementById('mySidenav').contains(e.target) && !document.getElementById('myMenu').contains(e.target)){
// Clicked in box
document.getElementById("mySidenav").style.width = "0px";
} else{
// document.getElementById("mySidenav").style.width = "0px";
}
});
</script>
<div id="mySidenav" class="sidenav">
About
Services
Clients
Contact
</div>
<span style="font-size:30px;cursor:pointer" id="myMenu" onclick="openNav()">☰ open</span>
1) Add a click event to your body
2) Check whether the target of the click has the class '.sidenav', or if it has a parent with that class.
3) If not, hide the sidebar, for example by setting 'display' to 'none'
you can try something like this
<style>
#mySidenav {
display: none;
}
</style>
<script>
document.body.addEventListener('click', function (e) {
if (e.target.parentNode.id === 'mySidenav') {
document.getElementById("mySidenav").style.display = "block";
e.preventDefault();
return;
}
document.getElementById("mySidenav").style.display = "none";
}, true);
function openNav() {
document.getElementById("mySidenav").style.display = "block";
}
</script>
<div id="mySidenav" class="sidenav">
About
Services
Clients
Contact
</div>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">☰ open</span>
$(function() {
$("#ham-icon").on("click", function(e) {
$("#mySidenav").addClass("cstm-w");
e.stopPropagation()
});
$(document).on("click", function(e) {
if ($(e.target).is("#ham-icon") === false) {
$("#mySidenav").removeClass("cstm-w");
}
});
});
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;
}
.cstm-w {
width: 250px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="mySidenav" class="sidenav">
About
Services
Clients
Contact
</div>
<span style="font-size:30px;cursor:pointer" id="ham-icon">☰ open</span>

How should i move div after decreasing width?

My problem is that i that i want to move the red div out from the black overlay after decreasing width, so for example: when the width is 500px, the red div should appear in the green box (body).
I've tried to use display: none; and display: inline, but then i realized that it just work if you want the div in the same place. But i want to change position, so that the red div goes from one position to another. Hope someone can help!
Thanks!
function openNav() {
document.getElementById("myNav").style.width = "100%";
}
function closeNav() {
document.getElementById("myNav").style.width = "0%";
}
body {
font-family: 'Lato', sans-serif;
background: green;
}
.overlay {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.9);
overflow-x: hidden;
transition: 0.5s;
}
.overlay-content {
position: relative;
width: 200px;
background: red;
height: 200px;
margin: 20px;
}
.overlay a {
padding: 8px;
text-decoration: none;
font-size: 36px;
color: #818181;
display: block;
transition: 0.3s;
}
.overlay .closebtn {
position: absolute;
top: 20px;
right: 45px;
font-size: 60px;
}
#media screen and (max-height: 450px) {
.overlay a {
font-size: 20px
}
.overlay .closebtn {
font-size: 40px;
top: 15px;
right: 35px;
}
}
<div id="myNav" class="overlay">
×
<div class="overlay-content"></div>
</div>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">☰</span>
Codepen: https://codepen.io/anon/pen/XVyoKp
Use fixed positioning in your closeNav & openNav It makes the position fixed to a spot in the browser window.
function openNav() {
document.getElementById("myNav").style.width = "100%";
var overlay = window.document.getElementsByClassName("overlay-content")[0];
overlay.style.left = "-1000px";
}
function closeNav() {
document.getElementById("myNav").style.width = "0%";
var overlay = window.document.getElementsByClassName("overlay-content")[0];
overlay.style.position = "fixed";
overlay.left = "40px;"
}

Nav bar to the right

I am trying to write a simple navbar pulling from the right of the screen, and I have the below code.
var isOpen = false;
function openNav() {
if (false == isOpen) {
document.getElementById("myNewsNav").style.width = "250px";
document.getElementById("main").style.marginLeft = "250px";
//document.body.style.backgroundColor = "rgba(0,0,0,0.4)";
isOpen = true;
} else {
closeNav();
}
}
function closeNav() {
document.getElementById("myNewsNav").style.width = "0";
document.getElementById("main").style.marginLeft = "0";
document.body.style.backgroundColor = "white";
isOpen = false;
}
body {
font-family: "Lato", sans-serif;
transition: background-color .5s;
}
.newsnav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.newsnav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;
}
.newsnav a:hover {
color: #f1f1f1;
}
.newsnav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
#main {
transition: margin-left .5s;
padding: 16px;
}
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="myNewsNav" class="newsnav">
×
About
Services
Clients
Contact
</div>
<div id="main">
<h2>Sidenav Push Example</h2>
<p>Click on the element below to open the side navigation menu, and push this content to the right. Notice that we add a black see-through background-color to body when the sidenav is opened.</p>
<span style="font-size:30px;cursor:pointer" onclick="openNav()"> open</span>
</div>
</body>
It works fine at the left side. i tried changing the margin left and adding float: right attribute to the css, but still it isn't pulling the nav bar from the right. It always shows on the left side. What is wrong here?
EDIT:
Any which way, can I make the slider start from a specific div only?
<div id="Slider_Should_begin_From_This_Point_of_screen"></div>
Like for eg: I want the slider to slide in and out only from this div onwards.
You need to do just two things.
1) Change the marginLeft to marginRight in the function "openNav"
document.getElementById("main").style.marginRight = "250px";
2) The .newsnav css has a property "left" set to 0, you have to change that to right: 0;
.newsnav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
right: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
That is all you have to do.
As per your updated request, it now slides from the right and below the span element:
var isOpen = false;
function openNav() {
if(isOpen == false) {
document.getElementById("myNewsNav").style.width = "250px";
//document.getElementById("main").style.marginRight = "250px";
//document.body.style.backgroundColor = "rgba(0,0,0,0.4)";
isOpen=true;
} else {
closeNav();
}
}
function closeNav() {
document.getElementById("myNewsNav").style.width = "0";
//document.getElementById("main").style.marginRight = "0";
//document.body.style.backgroundColor = "white";
isOpen=false;
}
body {
font-family: "Lato", sans-serif;
transition: background-color .5s;
}
.newsnav {
/*height: 100%;*/
width: 0;
position: relative; /* modified */
z-index: 999; /* changed to a higher number */
background-color: #111;
overflow-x: hidden;
transition: .5s;
padding-top: 60px;
}
.wrapper {
position: absolute; /* taken out of the document flow so that it doesn't affect other elements placed below */
right: 0; /* positioned at the right side of the screen */
z-index: 999; /* just in case */
}
.newsnav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: .3s;
}
.newsnav a:hover {
color: #f1f1f1;
}
.newsnav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
#main {
/*transition: margin-left .5s;*/
padding: 16px;
}
<div id="main">
<h2>Sidenav Push Example</h2>
<p>Click on the element below to open the side navigation menu, and push this content to the right. Notice that we add a black see-through background-color to body when the sidenav is opened.</p>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">open</span>
<div class="wrapper">
<div id="myNewsNav" class="newsnav">
×
About
Services
Clients
Contact
</div>
</div>
<p>Lorem ... so that you can see that this element isn't affected ...</p>
</div>
Noticeable changes:
Moved the #myNewsNav div below the span element because of the document flow.
Wrapped the #myNewsNav div with an additional div
Commented out unnecessary things
You have position fixed left:0 that will keep it on the left side.
function closeNav() {
document.getElementById("myNewsNav").style.width = "0";
document.getElementById("main").style.marginRight= "0";
document.body.style.backgroundColor = "white";
isOpen=false;
}
var isOpen = false;
function openNav() {
if(false == isOpen) {
document.getElementById("myNewsNav").style.width = "250px";
document.getElementById("main").style.marginRight = "250px";
//document.body.style.backgroundColor = "rgba(0,0,0,0.4)";
isOpen=true;
}else{
closeNav();
}
}
body {
font-family: "Lato", sans-serif;
transition: background-color .5s;
}
.newsnav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
right: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.newsnav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;
}
.newsnav a:hover {
color: #f1f1f1;
}
.newsnav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
#main {
transition: margin-left .5s;
padding: 16px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<div id="myNewsNav" class="newsnav">
×
About
Services
Clients
Contact
</div>
<div id="main">
<h2>Sidenav Push Example</h2>
<p>Click on the element below to open the side navigation menu, and push this content to the right. Notice that we add a black see-through background-color to body when the sidenav is opened.</p>
<span style="font-size:30px;cursor:pointer" onclick="openNav()"> open</span>
</div>
<script>
</script>
</body>
</html>
Bro - right:0 :)
.newsnav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0; // !here should right:0
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
And replace marginLeft to marginRight in openNav() and in closeNav() functions:
document.getElementById("main").style.marginLeft = "250px";

Sidebar navigation toggle with single button

I have implemented the following sidebar navigation into a simple admin. I've got it working and moved to the right side. I would like to have it appear and disappear using a single button rather than a separate close and open button. I tried modifying the JS with an onToggle function that if isOpen was null, it would open the panel and then set isOpen to true and then the next time it ran, it would delete isOpen. I'm very new at JS and this failed so I thought I'd ask here. How do I get this puppy appearing and disappearing with a single button?
http://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_sidenav
Thank you kindly.
<!DOCTYPE html>
<html>
<style>
body {
font-family: "Lato", sans-serif;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 60px;
left: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s
}
.sidenav a:hover, .offcanvas a:focus{
color: #f1f1f1;
}
.closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px !important;
margin-left: 50px;
}
#media screen and (max-height: 450px) {
.sidenav {padding-top: 15px;}
.sidenav a {font-size: 18px;}
}
</style>
<body>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">☰ open</span>
<div id="mySidenav" class="sidenav">
×
About
Services
Clients
Contact
</div>
<h2>Animated Sidenav Example</h2>
<p>Click on the element below to open the side navigation menu.</p>
<script>
function openNav() {
var e = document.getElementById("mySidenav");
if (e.style.width == '250px')
{
e.style.width = '0px';
}
else
{
e.style.width = '250px';
}
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
}
</script>
</body>
</html>
This is the same code with little modifications in the openNav() method. For triggering the sideNavbar with a button, it needs to be visible before and after triggering the sideNavBar. So i have moved the view button to the top and i have modified the top property of sidenav to keep the trigger button visible even after activation
You can view this in action here: https://jsfiddle.net/ngohrvk1/
I know the question is tagged with JavaScript and you probably don't want to change the markup or add new elements. But if you could, here's a pure CSS solution that works.
body {
margin: 0;
}
.sidebar-toggle {
position: absolute;
left: 0;
top: 0;
z-index: 2;
padding: 10px;
background: red;
color: white;
}
#sidebar-toggle-input {
display: none;
}
#sidebar-toggle-input+label:before {
content: "➡️";
}
#sidebar-toggle-input:checked + label:before {
content: "❌"
}
.sidebar {
position: fixed;
width: 200px;
transition: 0.3s;
background: blue;
height: 100vh;
top: 0;
left: 0;
transform: translateX(-100%);
}
#sidebar-toggle-input:checked ~ .sidebar {
transform: none;
}
<input type="checkbox" id="sidebar-toggle-input" />
<label class="sidebar-toggle" for="sidebar-toggle-input"></label>
<div class="sidebar"></div>
This code will help you out, I have created a function and saving data-isshown attribute on the element, to get whether the element is shown or not, we can decide this on the basis of the width as well but this is more generic approach
function toggleNav() {
var element = document.getElementById("mySidenav")
var shown = element.getAttribute("data-isshown");
if (shown == "true") {
element.setAttribute("data-isshown", "false");
element.style.width = "0";
} else {
element.setAttribute("data-isshown", "true");
element.style.width = "250px";
}
}
Whole code would look like this
function toggleNav() {
var element = document.getElementById("mySidenav")
var shown = element.getAttribute("data-isshown");
if (shown == "true") {
element.setAttribute("data-isshown", "false");
element.style.width = "0";
} else {
element.setAttribute("data-isshown", "true");
element.style.width = "250px";
}
}
body {
font-family: "Lato", sans-serif;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s
}
.sidenav a:hover,
.offcanvas a:focus {
color: #f1f1f1;
}
.closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px !important;
margin-left: 50px;
}
#media screen and (max-height: 450px) {
.sidenav {
padding-top: 15px;
}
.sidenav a {
font-size: 18px;
}
}
<div id="mySidenav" class="sidenav">
×
About
Services
Clients
Contact
</div>
<h2>Animated Sidenav Example</h2>
<p>Click on the element below to open the side navigation menu.</p>
<span style="font-size:30px;cursor:pointer" onclick="toggleNav()">☰ open</span>

Categories

Resources