How to toggle open & close menu - javascript

I'm trying to make a slide menu but I don't know how would I close it back.
Basically i'm trying to do something like this website https://zero.nyc/
const menu = document.querySelector('aside');
const nav = document.querySelector('nav');
menu.addEventListener('click', () => {
nav.style.marginLeft = '0';
menu.style.left = '97vw';
})
aside {
border-right: 1px solid #e2e2e2;
width: 3vw;
height: 100vh;
line-height: 100vh;
position: fixed;
top: 0;
left: 0;
transition: 1s;
}
nav {
width: 97vw;
height: 100vh;
margin-left: -100vw;
transition: 1s;
}
<aside>
menu
</aside>
<nav>
<ul>
<li>Home</li>
<li>ABOUT</li>
<li>Contact</li>
</ul>
</nav>

Use css classes and toggle them on or off on in your click method instead of setting the styles through javascript.
Snippet:
const menu = document.querySelector('aside');
const nav = document.querySelector('nav');
menu.addEventListener('click', () => {
nav.classList.toggle("margin");
menu.classList.toggle("left");
})
aside {
border-right: 1px solid #e2e2e2;
width: 3vw;
height: 100vh;
line-height: 100vh;
position: fixed;
top: 0;
left: 0;
transition: 1s;
-webkit-transition: 1s;
-ms-transition: 1s;
-moz-transition: 1s;
}
nav {
width: 97vw;
height: 100vh;
margin-left: -100vw;
transition: 1s;
-webkit-transition: 1s;
-ms-transition: 1s;
-moz-transition: 1s;
}
.margin {
margin-left: 0;
}
.left {
left: 97vw;
}
<aside>
menu
</aside>
<nav>
<ul>
<li>Home</li>
<li>ABOUT</li>
<li>Contact</li>
</ul>
</nav>

I would create css classes to toggle within your click event handler instead of manually changing the styles.
On click you're basically going to:
Grab the elements you want to change
Toggle the classes using classList.toggle (if you're not worried about < ie9)
Benefit of using classes is once you remove it, the element simply reverts. It's also more maintainable because you don't have to keep track of the styles you change.

Use transform: translateX() instead of margin. You also have to write some state of your menu i.e. opened/closed. You can use a css class for that, and in your eventListener you can check if menu is opened, then onClick animate from translateX(0) to translateX(-100%)and remove opened class.
Or you can write styles with transitions, or #keyframes animations, everything will work. Just build the idea of storing opened state first.

Related

Animation bug on navigational links on a mobile menu

I have mobile navigation bar that toggles on clicking the burger and everything works fine. The navigational links have animation that needs to be triggered every time when there is no animation on them (achieved with JavaScript, code will be shown below) and everything works fine until the moment I click on one navigational link. So the navigation bar closes, and the animation is triggered on closing, thus not on opening and the next time I click on the burger in order to open the menu the animation does not play. BUT, the thing that confuses me the most is that after clicking on one of the navigational links, on the next menu-opening the animation is here and everything works fine (the bug comes after clicking on one of the navigational links).
How to make the animation play every time on opening the menu?
HTML code:
<nav>
<div class="logo">
Portfolio
</div>
<ul class="nav-links">
<li>Home</li>
<li>About Me</li>
<li>Skills</li>
<li>Contact</li>
</ul>
<div class="burger">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
</nav>
CSS code:
// if nav is active translate him to 0 (since he is translated)
.nav-active {
transform: translateX(0%);
}
.nav-links {
position: absolute;
right: 0;
height: 93vh;
top: 7vh;
background-color: white;
box-shadow: 0 5px 50px white;
display: flex;
flex-direction: column;
justify-content: center;
width: 40%;
transform: translateX(110%);
transition: transform 0.5s ease-in;
}
.nav-links li {
opacity: 0;
list-style: none;
display: flex;
align-items: center;
flex-direction: column;
}
.nav-links a {
margin-left: 0;
color: #3e689d;
font-size: 2.2em;
margin-bottom: 50px;
transition: 0.5s ease;
padding: 30px 30px;
}
.burger div {
width: 40px;
height: 5px;
background-color: white;
margin: 5px;
transition: all 0.5s ease;
}
//animation for burger
.toggle .line1 {
transform: rotate(-45deg) translate(-6.5px, 7.5px);
}
.toggle .line2 {
background-color: black;
transform: translateX(-100px) scale(0);
}
.toggle .line3 {
transform: rotate(45deg) translate(-6.5px,-7.5px);
}
// animation for links
#keyframes navLinkFade {
from {
opacity: 0;
transform: scale(0) rotate(90deg);
}
to {
opacity: 1;
transform: scale(1);
}
}
JavaScript code:
const navSlide = () => {
const burger = document.querySelector('.burger');
const nav = document.querySelector('.nav-links');
const navLinks = document.querySelectorAll('.nav-links li');
const navigationItems = document.querySelectorAll('.nav-links a');
// if there is no animation on the links add the one that I have declared in CSS
burger.addEventListener('click', () => {
nav.classList.toggle('nav-active');
navLinks.forEach((link, index) => {
// I think the problem is in this if/else statement
if (link.style.animation) {
link.style.animation = ''
}
else {
link.style.animation = `navLinkFade 0.5s ease forwards ${index / 7 + 0.5}s`;
}
});
// toggle the burger animation that I have declared in CSS
burger.classList.toggle('toggle');
// close the menu and the burger on clicking on one of the navigational links
navigationItems.forEach((navigationItem) => {
navigationItem.addEventListener("click", () => {
nav.classList.remove('nav-active');
burger.classList.remove('toggle');
});
});
});
}
navSlide();
Thank you, grateful for any help.
I just noticed that I forgot to remove the animation in the event listener that had the task to close the navigation bar and the problem was occurring because the navigation bar was closing but the navigational links still had the animation on them. So to solve my problem I just needed to add two lines of code that will remove the animation when the navigation bar closes.
Here is the solution :
navigationItems.forEach((navigationItem) => {
navigationItem.addEventListener("click", () => {
//I was missing the next two lines of code to remove the animation from my navigational links when the navigational bar closes
navLinks.forEach((link) => {
link.style.animation = ''
});
nav.classList.remove('nav-active');
burger.classList.remove('toggle');
});
});
Problem solved.

How to end CSS transition with jquery or js?

I want to end my css transition with jquery or js. I don't mean pause, I want to end them, as if they became 100% done. I have css transitions and not animations.
The properties I am using transition on are top and left, and it is a position absolute element.
You can simply override the transition-property rule to none.
#el {
position: relative;
left: 0;
top: 25px;
width: 50px;
height: 50px;
transition: all 5s linear;
background: red;
}
body:hover #el{
left: calc(100vw - 50px);
}
button:active + #el {
transition-property: none;
}
:root,body{margin:0}
<button>stop transition</button>
<div id="el"></div>
Now how you trigger this is up to you, it can be using a special class, or any other condition.
Hello your question is kinda ambiguous.
if you are using transition instead of animation you can control the flow of it in the same css example :
transition: background-color .2s linear 0s; /*Standard*/
If you want to interrupt the transition with JS you can assign other Css valor to an different class name or property when some action you want is triggered.
.normal{
transition: background-color .2s linear 0s; /*Standard*/
}
[stop = yes] {
background: black;
}
document.body.addEventListener('mouseover', function(e){
e.stopPropagation();
if(someting you want){
document.queryselector(".normal").setAttribute("stop","yes");
}
else{
document.queryselector(".normal").setAttribute("stop","no");
}
},false);
if something you want were triggered then the atribute will be set to the no
transition and this also cut off the running one.
$('.toggle-animation').click(function(){
$('.element').stop(true).toggleClass('animating');
});
.element{
top: 0px;
left: 0px;
width: 100px;
height: 100px;
position:relative;
background: red
}
.animating{
top: 100px;
left: 100px;;
transition: all 5s linear 0s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="element"></div>
<button type="button" class="toggle-animation">Click me</button>

ease toggle with jquery/html/css3 not working in ie properly

JSfiddle
Here is a fiddle for what I am trying to do. I am trying to use pure css with exception of jquery to toggle the appropriate class and let the css transitions handle the rest. I know this isn't supported by old IE's which is fine with me at this point.
What is happening is for when ever I click the link text the on/off the slider moves and eases just fine. However, when I hit the actual slider portion of the button it moves over suddenly with no easing. Here is the code:
HTML
<a href="#" class="on-off">
<span class="on">ON</span>
<span class="off">OFF</span>
<span class="slider right ease"></span>
</a>
CSS
.on-off {
display: inline-block;
position: relative;
padding: 5px;
background: #ff8600;
border-radius: 5px;
border: 1px solid #b8baba;
}
.on-off .on {
margin-right: 10px;
}
.slider {
position: absolute;
width: 50%;
height: 100%;
background: #fff;
z-index: 2;
border-radius: 5px;
border: 1px solid #b8baba;
}
.right {
top: 0;
right: 0;
}
.left {
top: 0;
right: 50%;
}
.ease {
-webkit-transition: all .5s ease;
-moz-transition: all .5s ease;
-ms-transition: all .5s ease;
-o-transition: all .5s ease;
transition: all .5s ease;
}
Javascript
$('.on-off').on('click', function() {
$slider = $('.slider');
if ($slider.hasClass('right')) {
$('.slider').removeClass('right');
$('.slider').addClass('left');
} else {
$('.slider').removeClass('left');
$('.slider').addClass('right');
}
})
This does work in chrome/firefox just fine. Just not IE10/11. I am trying to use graceful degradation. Keep things lightweight so if css can handle it not to use javascript where also it has basic functionality it just might toggle rather than ease in unsupported browsers. I know IE10/11 supports ease as it is working. just not when I click that particular area of the button.
Thanks for the help.
Hey this is going to sound dumb, but here's the solution
$('.on-off').on('click', function() {
$slider = $('.slider');
if ($slider.hasClass('right')) {
$('.slider').addClass('left');
$('.slider').removeClass('right');
} else {
$('.slider').addClass('right');
$('.slider').removeClass('left');
}
});
Add before you remove, and add a semicolon to your function.

How to make a navigation which reveals on hover

I would like to create a navigation that reveals on hover however I am not sure how to go about doing it. I would like to do it how they have done it in the top left hand corner when you hover on the name: http://higz.ghosted.net/
I would like it to be just like the example and the menu which display to be a list so <ul> <li>
Here is an example related to what you are looking at- still there some issue you have to fix, but i have giving you the quick start.
final result -
http://jsbin.com/parok/4/edit?html,css,js,output
HTML -
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id='navigation'>
<div class='logo'></div>
<div class='menus'>
<ul>
<li><a href='#'>Home page</a></li>
<li><a href='#'>About</a></li>
<li><a href='#'>Service</a></li>
<li><a href='#'>Contact</a></li>
</ul>
</div>
</div>
</body>
</html>
CSS -
body {margin:0; padding: 0;}
#navigation {
width: 500px;
height: 100px;
background: wheat;
border-radius: 5px;
}
.logo {
width: 100px;
height: 100px;
background: red;
border-radius: 50px;
float:left;
margin-right: 20px;
font-size: 20px;
text-align:center;
color: white;
display: block;
}
.logo p {
margin-top: 30px;
}
.menus {
position: relative;
opacity: 0;
top: 40px;
}
.logo:hover {
cursor: pointer;
}
.menus a:link, .menus a:visited {color: darkgray; text-decoration: none; text-transform: uppercase;}
.menus ul {
list-style:none;
}
.menus ul li {
display: inline-block;
padding-right: 15px;
}
jQuery -
$(function(){
$('.logo').mouseover(function(){
//console.log('foo');
$('.menus').animate({
'opacity': 1,
'left': '20px'
}, 500);
}).mouseout(function(){
//console.log('bar');
$('.menus').animate({
'opacity': 0,
'left': '0px'
}, 500);
});
});
Use jquery and ajax if you want to do it Asynchronously. I prefer do it by calculating the navigation at run time using ajax provided they are not static pages. (depends on server side language you are using)
Otherwise just use jquery to do this.
With the hover event of jQuery you show the navigation and on just hide it :
$("#id").hover(function(){
$("#id").show();
});
$("#id").mouseleave/blur(function(){
$("#id").hide();
});
and do paste your code where you want to achieve it. Otherwise we can only put up theory here. We are not supposed to write entire code.
This is not a hard task to achieve..
Lets get started:
Step 1) Build a sample html content to be displayed on hover
<div class="toggle-display">
Your HTML
</div>
Step 2) Lets give it some css
.toggle-display {
opacity: 0.1; /*set to 0.0 to hide it completely */
width: 200px;
height: 50px;
border: 1px solid #333;
/* transitions */
-o-transition: all .3s linear;
-webkit-transition: all .3s linear;
-moz-transition: all .3s linear;
transition: all .3s linear;
}
.toggle-display:Hover {
opacity: 1.0;
}
3) Put it all together
<html>
<head>
<style>
.toggle-display {
opacity: 0.1; /*set to 0.0 to hide it completely */
width: 200px;
height: 50px;
border: 1px solid #333;
/* transitions */
-o-transition: all .3s linear;
-webkit-transition: all .3s linear;
-moz-transition: all .3s linear;
transition: all .3s linear;
}
.toggle-display:Hover {
opacity: 1.0;
}
</style>
</head>
<body>
<div class="toggle-display">
Your content
</div>
</body>
</html>
Here is a sample
Tried and works fine,
Hope this helped you (If so, mark this answer as ok please),
Best regards.
Alberto
Use Jquery:
$('.blog_title').on('mouseenter', function(){
$('ul').show();
});
In reality you want to animate and not just show(). It looks like the menu fades in and moves from the left.
Also you want to give your ul a class name otherwise this code will affect all the ul's in the HTML.
And you do the reverse on 'mouseleave'.

How to make my off-canvas menu scroll?

I've been trying to get my off-canvas menu working by scrolling particularly in landscape mode because the list itself runs longer than the size of the screen. This menu is shown below 768px for tablet and mobile.
To clarify, the menu items go longer then the screen space and I'm trying to get it to scroll by doing multiple methods, such as overflow-y: scroll, -webkit-overflow-scrolling: touch and more (all works in desktop browser at phone sizes when I was messing in the inspector).
I've been trying everything to inspect the elements and get the menu to scroll when needed and not the background (website/page behind menu). Here is some of my markup and styling, I'm also including a live link to inspect as its way easier than pasting everything in here. Any help is kindly appreciated!
LIVE LINK
<body class="cbp-spmenu-push">
<nav class="cbp-spmenu cbp-spmenu-vertical cbp-spmenu-left mobile" id="cbp-spmenu-s1">
<a class="m-storyLink mobile-nav-link" href="">1</a>
2
3
3
Contact Us
4
<ul class="mobile-social">
<li></li>
<li></li>
<li></li>
</ul>
</nav>
<header id="header" class="header headroom headroom--pinned">
<!-- mobile header -->
<div class="mobile">
<button id="showLeftPush">MENU</button>
<img src="img/home/logo.png" alt="#"
</div>
And CSS
.cbp-spmenu-push-toright {
left: 240px!important;
}
.cbp-spmenu-push-toright.cbp-spmenu-push {
overflow: hidden;
position: fixed;
}
/* General styles push menu*/
.cbp-spmenu {
background-color: #000;
position: fixed;
font-family: FranklinGothicLTCom-BkCm, "Arial Narrow", sans-serif;
padding: 110px 0 0 0;
}
.mobile-nav-link {
background-position: 10px center;
}
/* Orientation-dependent styles for the content of the menu */
.cbp-spmenu-vertical {
width: 240px;
min-height: 300px;
height: 100%;
top: 0;
z-index: 1000;
-webkit-transition: all 250ms ease-in-out;
-moz-transition: all 250ms ease-in-out;
-ms-transition: all 250ms ease-in-out;
-o-transition: all 250ms ease-in-out;
transition: all 250ms ease-in-out;
overflow-y: scroll !important;
-webkit-overflow-scrolling: touch;
}
.cbp-spmenu-left {
left: -240px;
}
.cbp-spmenu-right {
right: -240px;
}
.cbp-spmenu-left.cbp-spmenu-open {
left: 0px;
}
.cbp-spmenu-right.cbp-spmenu-open {
right: 0px;
}
/* Horizontal menu that slides from the top or bottom */
.cbp-spmenu-top {
top: -150px;
}
.cbp-spmenu-bottom {
bottom: -150px;
}
.cbp-spmenu-top.cbp-spmenu-open {
top: 0px;
}
.cbp-spmenu-bottom.cbp-spmenu-open {
bottom: 0px;
}
/* Push classes applied to the body */
.cbp-spmenu-push {
position: relative;
left: 0;
-webkit-transition: all 250ms ease-in-out;
-moz-transition: all 250ms ease-in-out;
-ms-transition: all 250ms ease-in-out;
-o-transition: all 250ms ease-in-out;
transition: all 250ms ease-in-out;
}
LIVE LINK: http://bit.ly/1eGCShX
cbp-spmenu has a min-height of 550px. This is what is limiting your ability to scroll it in smaller resolutions.
Remove the min-height and you should be fine. Of course, do it as a media query, so it only is in effect on mobile devices.
-----------update----------------
not sure if you just changed it, but I took another look and now I don't see the min-height, but adding overflow:auto to the same cbp-spmenu element also makes it scroll.

Categories

Resources