Sliding menu, how to slide both in and out? - javascript

I am trying to build a menu that slides in and out with the press of a button. Also, when menu is opened, it should slide out when clicked any part of the screen.
So far I have managed to create everything except the slide out effect, now the slide just disappears, without moving from right to left.
var navBtn = document.getElementById("navBtn");
var navMenu = document.getElementById("navMenu");
var container = document.getElementById("container");
navBtn.addEventListener("click", showMenu);
container.addEventListener("click", hideMenu);
navMenu.style.display = "none";
function showMenu(){
if(navMenu.style.display !== "none"){
navMenu.style.display = "none"}
else{navMenu.style.display = "block", container.style.background = "rgba(0, 102, 199, 1)";}}
function hideMenu(){
if(navMenu.style.display = "block"){
navMenu.style.display = "none", container.style.background = "lightblue";}}
#main-container {
width: 350px;
height: 600px;
border: 1px solid black;
position: absolute;
overflow: hidden;
}
#container {
width: 350px;
height: 100%;
display: absolute;
z-index: 1;
background: rgba(0, 102, 199, 0.8);
}
#navBtn {
width: 50px;
height: 50px;
background: red;
position: absolute;
z-index: 999;
}
#navMenu {
width: 250px;
height: 100%;
background: blue;
position: absolute;
z-index: 9999;
top: 0;
animation-name: slidein;
animation-duration: .5s;
}
#-webkit-keyframes slidein {
0% {transform: translateX(-200px);}
100% {transform: translateX(0px);}
}
#navMenu.close {
animation-name: slideout;
animation-duration: .5s;
}
#-webkit-keyframes slideout {
0% {transform: translateX(0px);}
100% {transform: translateX(-200px);}
}
<div id="main-container">
<div id="navBtn"></div>
<div id="container">
<div id="navMenu"></div>
</div>
</div>
Maybe someone could show me a way to achieve this? Basically the slide in effect should be the same as the slide in, just in a reverse way.

function openNav() {
document.getElementById("mySidenav").style.width = "250px";
document.getElementById("main").style.marginLeft = "250px";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
document.getElementById("main").style.marginLeft = "0";
}
body {
font-family: "Lato", sans-serif;padding:40px;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #B971BB;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #fff;
display: block;
transition: 0.3s;
}
.sidenav a:hover {
color: #f1f1f1;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
#main {
transition: margin-left .5s;
padding: 16px;
}
#media screen and (max-height: 450px) {
.sidenav {padding-top: 15px;}
.sidenav a {font-size: 18px;}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div id="mySidenav" class="sidenav">
×
About
Services
Clients
Contact
</div>
<div id="main">
<h2>Sidena Example</h2>
<p>Click on the element below to open the side navigation menu, and push this content to the right.</p>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">☰ open</span>
</div>

html
<div id="main-container">
<div id="navBtn"></div>
<div id="container">
<div id="navMenu"></div>
</div>
</div>
jsCode
var navBtn = document.getElementById("navBtn");
var navMenu = document.getElementById("navMenu");
var container = document.getElementById("container");
navBtn.addEventListener("click", showMenu);
container.addEventListener("click", hideMenu);
//navMenu.style.display = "none"; // remove the display: none as you cannot animate display block to display none
function showMenu() {
container.classList.add('open');
}
function hideMenu() {
container.classList.remove('open');
}
and the css
#main-container {
width: 350px;
height: 600px;
border: 1px solid black;
position: absolute;
overflow: hidden;
}
#container {
width: 350px;
height: 100%;
z-index: 1;
background: rgba(0, 102, 199, 0.8);
transition: all 0.3s ease-in-out;
}
#navBtn {
width: 50px;
height: 50px;
background: red;
position: absolute;
z-index: 999;
}
#navMenu {
width: 250px;
height: 100%;
background: blue;
position: absolute;
z-index: 9999;
top: 0;
left: -250px;
transition: all 0.3s ease-in-out;
}
#container.open {
background: rgba(0, 102, 199,1);
}
#container.open #navMenu {
left: 0;
}

Looks like you attached the slide-out animation to a .close class that you never apply to the menu.
The easiest way to do this and to have more control is to add a class to the container, when the menu should be opened. afterwards just use css and left position along with transition to animate the menu. I'll provide code in a minute

Related

How to create a square box in which the border of the box will be filled by color depending on the value given on the box?

Just like the above image or an idea or reference to achieve this design, I appreciate the help or suggestion given by community thank you
I have got reference of progress bar which is circular but not able find an approach to solve it.
const boxes = document.querySelectorAll(".box");
const colors = ['red', 'blue', 'green', 'yellow', 'orange', 'violet']
boxes.forEach((box) => {
const insideContent = box.innerText;
box.style.border = `6px solid ${colors[insideContent]}`
})
#app {
display: flex;
}
.box {
width: 50px;
height: 50px;
margin: 10px;
background-color: cyan;
display: flex;
justify-content: center;
align-items: center;
}
<div id="app">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
As per your question I think this is what you are trying to achieve.
First define a pseudo class root
:root {
--color-val: blue;
}
Note: In order to use the --color-val you need to write it as color: var(--color-var) in CSS
Second use JavaScript to update the variable --color-val
let colors =
var root = document.querySelector(':root');
const delay = ms => new Promise(res => setTimeout(res, ms));
const colorChange = async () => {
await delay(1000);
color = colors[Math.floor(Math.random() * colors.length)]
console.log(color)
root.style.setProperty('--color-val', color);
};
colorChange()
Note:
Add the color list you want to select from or go to CodePen for a list of 1000+ hex codes.
Promise are used for asynchronous function and can be skipped by using setTimeOut for a delayed loop or if used with another eventlistener.
I apologize if I misunderstood the question. Wrote in a hurry and without beautyful visualisation, if you disassemble the principle, you can customize it.
h1 {
display: block;
margin:0 auto;
text-align: center;
padding-top:20%;
}
.container {
display:flex;
width: 150px;
height: 150px;
border: 1px solid black;
z-index: 110;
margin:0;
margin: -10px;
}
.top {
display:block;
background-color: green;
height: 24px;
width: 150px; /* gorizontal top */
animation: top 1s linear;
animation-fill-mode: forwards;
}
#keyframes top {
0% {
width: 0px;
}
100% {
width: 150px;
}
}
.right {
background-color: green;
height: 0%;/* right */
width: 32px;
animation: right 1s linear;
animation-fill-mode: forwards;
animation-delay: 1s;
z-index: 10;
}
#keyframes right {
0% {
height: 0%;
}
100% {
height: 100%;
}
}
.box {
position: fixed;
top: 32.5px;
left: 32.5px;
width: 100px;
height: 100px;
border: 1px solid black;
margin: auto;
z-index: 120;
margin: -10px -10px;
}
.bottom {
position: absolute;
top: 123px;
left: 150px;
background-color: green;
width: 0px;
height: 27px;
z-index: 10;
animation: bottom 1s linear;
animation-fill-mode: forwards;
animation-delay: 2s;
/* animation-direction: reverse; */
}
#keyframes bottom {
0% {
transform: translate(0,0);
}
100% {
transform: translate(-250px,0);
-webkit-transform: translate(-250px,0); /** Safari & Chrome **/
-o-transform: translate(-250px,0); /** Opera **/
-moz-transform: translate(-250px,0); /** Firefox **/
width: 250px;
}
}
.left {
position: absolute;
top: 122px;
background-color: green;
width: 25px;
height: 0px;
animation: left 1s linear;
animation-fill-mode: forwards;
animation-delay: 3s;
}
#keyframes left {
0% {
transform: translate(0,0);
}
100% {
transform: translate(0,-250px);
-webkit-transform: translate(0,-250px); /** Safari & Chrome **/
-o-transform: translate(0,-250px); /** Opera **/
-moz-transform: translate(0,-250px); /** Firefox **/
height: 277px;
}
}
<div class='head'>
<div class='container'>
<div class='top'></div>
<div class='box'>
<h1 id='timer'>
1
</h1>
</div>
<div class='right'></div>
<div class='bottom'></div>
<div class='left'></div>
</div>
</div>
<script type="text/javascript">
init()
function init()
{
sec = 0;
setInterval(tick, 1000);
}
function tick()
{ if (sec<3) { sec++
document.getElementById("timer").
childNodes[0].nodeValue = sec;
} else {
clearInterval(0);
}
}
</script>
Also, instead of the SetInterval script, you can take values from your block width and height styles and output a mathematical calculation in h1 instead of a stopwatch.
upd: After your comment, I decided to do what I wrote about above. You can play with values and math, I add a snippet of another solution that changes the progress bar from the entered values within the entered range. (of course, it would be easier on react than on pure js)
function grade () {
let grade = +document.getElementById("grade").value;
let range = +document.getElementById("range").value;
document.getElementById("timer").innerHTML = `${grade}/${range}`;
progress(grade,range)
}
function progress (value, grade) {
document.getElementById('1').style.backgroundColor = `white`
document.getElementById("left").className = "noactive";
document.getElementById('top').style.width = `0%`
document.getElementById('right').style.height = `0%`
document.getElementById('bottom').style.width = `0%`
let GradeValuSide = grade/4;
if (value <= GradeValuSide) {
document.getElementById('top').style.width =
`${value/GradeValuSide*100}%`
} else if (value > GradeValuSide && value <= (GradeValuSide*2)) {
document.getElementById('top').style.width = `100%`
document.getElementById('right').style.height =
`${(value-GradeValuSide)/GradeValuSide*100}%`
} else if (value >= grade/2 && value < (grade/4)*3) {
document.getElementById('top').style.width = `100%`
document.getElementById('right').style.height = `100%`
document.getElementById('bottom').style.width =
`${((((value-(GradeValuSide*2)) / GradeValuSide) *100) / 100) *27}%`
} else if (value >= grade-(grade/4) /* && value < value + 1 */) {
document.getElementById('top').style.width = `100%`
document.getElementById('right').style.height = `100%`
document.getElementById('bottom').style.width = `100%`
document.getElementById('1').style.backgroundColor = `green`
document.getElementById("left").className = "left";
document.getElementById('left').style.height =
`${(40 - (40 * ((((value-(GradeValuSide*3)) * 100) / GradeValuSide)/ 100)))}%`
}
}
h1 {
font-size:20px;
position: absolute;
left: 40px;
display: block;
margin: 0 auto;
align-items: center;
padding-top:10%;
}
.container {
display:flex;
width: 150px;
height: 150px;
border: 1px solid black;
margin:0;
margin: -10px;
}
div.top {
display:block;
background-color: green;
height: 24px;
width: 0%; /* gorizontal top */
z-index:999;
}
div.right {
position:relative;
background-color: green;
height: 0%;/* right */
width: 32px;
z-index: 9999;
}
.box {
position: fixed;
top: 32.5px;
left: 32.5px;
background-color:white;
width: 100px;
height: 100px;
border: 1px solid black;
margin: auto;
z-index: 120;
margin: -10px -10px;
}
.wrap{
position: relative;
}
div.bottom {
position: absolute;
top: 123px;
background-color: green;
width: 0%; /* 27 = 100% */
height: 27px;
float: right;
right: 78vw;
z-index: 100;
}
div.left {
position: absolute;
background-color: white;
width: 23px;
height: 40%;
top: 23px;
bottom: 10px;
left: 0;
float: top;
}
div.noactive {
position: absolute;
background-color: white;
width: 23px;
height: 0%;
top: 23px;
bottom: 10px;
left: 0;
float: top;
}
.items {
margin-top: 50px;
text-align: center;
}
.grade,
.value {
height: 15px;
width: 50px;
align-items: center;
}
<div class='head'>
<div id='1' class='container'>
<div id='top' class='top'></div>
<div class='box'>
<h1 id='timer'>1</h1>
<div class='items'>
value<input id='grade' class='grade' type=number oninput="grade()"/>
range<input id='range' class='value' type=number oninput="grade()"/>
</div>
</div>
<div id='right' class='right'></div>
<div id='bottom' class='bottom'></div>
<div id='left' class='noactive'></div>
</div>
</div>
<script src='app.js'></script>

Image slides that fades when navbar is hit

I'm trying to make a replica of the slider on top of this google page: https://www.google.com/doodles
If someone could make a replica of the image slider with the bars, that would be great! I've tried to on my own but can't figure it out. Here's my try if it's helpful!
JAVASCRIPT:
<script>
var imgArray = [
'images/img1.gif',
'images/img2.gif',
'images/img3.jpg',
'images/img4.jpg'],
curIndex = 0;
imgDuration = 3000;
function slideShow() {
document.getElementById('slider').className += "fadeOut";
setTimeout(function () {
document.getElementById('slider').src = imgArray[curIndex];
document.getElementById('slider').className = "";
}, 500);
curIndex++;
if (curIndex == imgArray.length) { curIndex = 0; }
}
</script>
HTML:
<img class="slidershow" id="slider" src="images/img1.gif" onmouseover="slideShow()">
<div id="navigation">
<label for="r1" class="bar" id="bar1"></label>
<label for="r2" class="bar" id="bar2"></label>
<label for="r3" class="bar" id="bar3"></label>
<label for="r4" class="bar" id="bar4"></label>
</div>
</div>
CSS: --> Honestly, I wrote so much CSS that I don't know which ones relate, so I might have left a few out. Need to clean that up - Apologize in advance
.nav_links {
list-style: none;
}
.nav_links li {
display: inline-block;
padding: 0px 20px;
}
.nav_links li a {
color: #009cdc;
transition: all 0.3s ease 0s;
}
.nav_links li:hover a {
color: #2772ff;
}
#top-content {
display: block;
}
latest-nav li#latest-nav-1 {
background-color: #fa4842;
}
#latest-nav li.off {
border-top: 15px solid #fff;
}
#latest-nav li.off {
height: 5px;
opacity: 0.35;
}
#latest-nav li {
cursor: pointer;
float: left;
height: 5px;
transition: opacity 0.15s ease,height 0.15s ease,border-top 0.15s ease;
-moz-transition: opacity 0.15s ease,height 0.15s ease,border-top 0.15s ease;
-webkit-transition: opacity 0.15s ease,height 0.15s ease,border-top 0.15s ease;
width: 16.6%;
}
.slidershow {
height: 400px;
overflow: hidden;
}
.middle {
position: absolute;
top: 50%;
left: 25%;
transform: translate(-50%,-50%);
}
#navigation {
position: absolute;
bottom: 35px;
left: 60%;
transform: translateX(-50%);
display: flex;
}
.bar {
border-top: 15px solid #fff;
width: 200px;
opacity: 0.35;
height: 5px;
cursor: pointer;
transition: 0.4s;
}
.slides {
width: 500%;
height: 100%;
display: flex;
margin-top: 30px;
}
.slide {
width: 20%;
transition: 0.6s;
}
.slide img {
display: block;
margin: auto;
max-height: 250px;
max-width: 600px;
width: auto;
}
latest .container img {
display: block;
margin: auto;
max-height: 250px;
max-width: 600px;
}
#bar1 {
background-color: #3875fc;
}
#bar2 {
background-color: #ff8809;
}
#bar3 {
background-color: #19be29;
}
#bar4 {
background-color: #fa4842;
}
Thanks so much!
I'm always happy to see newcomers devoting time to study. First of all, good job! Unfortunately I'm not a very good teacher, but I put together a little example of this slider you're working on. You can check it clicking here.
Basically what is going on is:
The HTML is divided into two sections: the slider & the navbar.
I hide all slides by default applying a display: none to them. They're only visible when I add an additional class.
Detect the hover method via javascript. Whenever the navbar item is hovered on, you will detect its position (I added a data attribute called data-position to find out which position it is) and show the correspondent slider.
So, if the navbar has the data-position of 2, I know that I must show the second slide. To do that, I use .slider .slider-item:nth-child(2).
As I mentioned I'm not the best at explaining, but I hope this helps you out a little bit. Keep studying and don't give up!
HTML:
<div class="wrapper">
<div class="slider">
<div class="slider-item slider-item--visible">
hello item 1
</div>
<div class="slider-item">
hello item 2
</div>
<div class="slider-item">
hello item 3
</div>
</div>
<nav class="navbar">
<span class="navbar-item navbar-item--selected" data-position="1"></span>
<span class="navbar-item" data-position="2"></span>
<span class="navbar-item" data-position="3"></span>
</nav>
</div>
CSS
.wrapper{
max-width: 1000px;
width: 100%;
margin: 0 auto;
display: block;
}
/* Slider */
.slider{
max-width: 100%;
width: 100%;
}
.slider-item{
display: none;
}
.slider-item--visible{
display: block;
}
/* Navbar */
.navbar{
max-width: 100%;
display: flex;
align-items: flex-end;
height: 8px;
}
.navbar-item{
max-width: 33.3%;
width: 100%;
display: block;
height: 5px;
cursor: pointer;
opacity: .5;
transition: all .32s ease;
}
.navbar-item--selected{
height: 8px;
opacity: 1;
}
/* Meaningless styles (colors) */
.navbar-item:nth-child(1){
background: salmon;
}
.navbar-item:nth-child(2){
background: lightblue;
}
.navbar-item:nth-child(3){
background: #19be29;
}
Javascript
const $navbars = document.querySelectorAll(`.navbar-item`);
function removeSelected(){
const $selected = document.querySelectorAll(`.navbar-item--selected, .slider-item--visible`);
if (!$selected){
return;
}
for (let each of $selected){
each.classList.remove("navbar-item--selected");
each.classList.remove("slider-item--visible");
}
}
for (let each of $navbars){
each.addEventListener("mouseover", function(){
removeSelected();
const position = each.getAttribute("data-position");
const $item = document.querySelector(`.slider .slider-item:nth-child(${position})`)
each.classList.add("navbar-item--selected")
$item.classList.add("slider-item--visible");
});
}

CSS3 transition not working on JS scrollup fixed div transition

I was trying a javascript function to fix a part of header on scrollup. It's working fine but I want to make the movement of fixed part smooth by adding transition property of CSS3. I tried but its not working. Request your help plz.
window.onscroll = myFunction;
function myFunction() {
if(document.body.scrollTop > 200 || document.documentElement.scrollTop > 200) {
document.getElementById("hdr_nav").style.position = "fixed";
} else {
document.getElementById("hdr_nav").style.position = "";
}
}//end function
*{margin: 0; padding: 0; box-sizing: border-box; -webkit-box-sizing: border-box; }
body {height: 3000px;}
.hdr_box {float: left; width: 100%; height: 65px; background: #eff1f2; position: relative; padding: 0; margin: 0;}
.hdr_box > .row1 {
float: left;
width: 100%;
height: 20px;
padding: 15px;
}
nav {
float: left;
width: 100%;
height: auto;
background: #e4e6e8;
position: relative;
transition: all 1s;
-webkit-transition: all 1s;
-moz-transition: all 1s;
}
nav ul {
list-style: none;
float: left;
width: 100%;
padding: 0;
margin: 0;
}
nav ul li {
float: left;
width: auto;
border-right: solid 1px #cacaca;
}
nav ul li a {
float: left;
width: auto;
padding: 16px;
text-align: center;
font-size: 14px;
}
<div class="hdr_box" id="hdr">
<div class="row1" id="hdr_row1"><h3>CompanyName</h3></div>
</div>
<nav id="hdr_nav">
<ul>
<li>About Us</li>
<li>Business</li>
<li>Our Work</li>
<li>Challenges</li>
</ul>
</nav>
That is because you change the position property from absolute to fixed and that can't be animated / transitioned. Transitions only work for properties with a unit, eg. px, rem, %, or stuff like opacity.
You can fix it however with a keyframe animation:
nav.is-fixed {
position: fixed;
animation: scroll .5s ease-out;
}
#keyframes scroll {
from {
transform: tranlateY(-100%);
}
to {
transform: tranlateY(0%);
}
}
Make sure to prefix #keyframes and transform if needed.
And a little change to the JS:
window.onscroll = myFunction;
function myFunction() {
var scrollAmount = document.body.scrollTop || document.documentElement.scrollTop;
var nav = document.getElementById("hdr_nav");
if(scrollAmount > 200) {
nav.classList.add('is-fixed');
} else {
nav.classList.remove('is-fixed');
}
}
https://jsfiddle.net/41nspon8/3/
add new CSS rule
.nav-fixed {
position: fixed;
-webkit-animation: slideInDown 450ms 1 ease-in-out;
}
#-webkit-keyframes slideInDown {
from {transform: translate(0%, -100%); }
to {transform: translate(0%, 0%); }
}
modify your js code
//document.getElementById("hdr_nav").style.position = "fixed";
document.getElementById("hdr_nav").classList.add("nav-fixed");
} else {
//document.getElementById("hdr_nav").style.position = "";
document.getElementById("hdr_nav").classList.remove("nav-fixed");
https://jsfiddle.net/13m8u7xm/

How do I get my button to work where it is clicked any place?

At the moment my hamburger button works just fine before it transforms, however after the hamburger button tranforms to the red "X" button if you click on any part of the "X" the button will transform, but it will not close the menu like it should. I can not find where I messed up.
Here is jsfiddle: https://jsfiddle.net/ex3z5o8L/
Here is the code:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
*{
margin: 0px;
padding: 0px;
font-family: "Verdana";
}
#image {
position: relative;
z-index: -1 ;
height: 100vh;
width: 100%;
}
#content {
position: relative;
height: 100vh;
width: 100%;
background-color:#4d5555;
}
#footer {
position: relative;
width: 100%;
height: 100vh;
background-color:#ffffff;
}
div#header #fullScreenNav{
position:fixed;
height:0px;
width:100%;
background:#000;
top:0px;
left:0px;
overflow:hidden;
z-index:2;
}
#fullScreenNavbtn{
background: #f3f3f3;
padding: 10px;
position: absolute;
z-index: 1 ;
top: 70vh;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%)
}
/* ---------------------------------------------------------Start Of Hamburger Button------------------------------------------------------- */
.c-hamburger {
display: block;
position: fixed;
overflow: hidden;
margin: 0;
padding: 0;
width: 64px;
height: 64px;
font-size: 0;
text-indent: -9999px;
appearance: none;
box-shadow: none;
border-radius: none;
border: none;
cursor: pointer;
transition: background 0.1s;
border-radius:10px;
background: transparent;
right:5px;
top:5px;
z-index: 3;
}
.c-hamburger:focus {
outline: none;
}
.c-hamburger:hover span,
.c-hamburger:hover span::before,
.c-hamburger:hover span::after
{background: black;}
.c-hamburger span {
display: block;
position: absolute;
top: 28px;
left: 10px;
right: 10px;
height: 8px;
background: #e6e6e6;
border-radius:100px;
}
.c-hamburger span::before,
.c-hamburger span::after {
position: absolute;
display: block;
left: 0;
width: 100%;
height: 8px;
background-color: #e6e6e6;
content: "";
border-radius:100px;
}
.c-hamburger span::before {
top: -15px;
}
.c-hamburger span::after {
bottom: -15px;
}
.c-hamburger--htx {
}
.c-hamburger--htx span {
}
.c-hamburger--htx span::before,
.c-hamburger--htx span::after {
transition-duration: 0.1s, 0.1s;
transition-delay: 0.1s, 0s;
}
.c-hamburger--htx span::before {
transition-property: top, transform;
}
.c-hamburger--htx span::after {
transition-property: bottom, transform;
}
/* active state, i.e. menu open */
.c-hamburger--htx.is-active {
background-color: #cb0032;
}
.c-hamburger--htx.is-active span {
background: none;
}
.c-hamburger--htx.is-active span::before {
top: 0;
transform: rotate(45deg);
background: white;
}
.c-hamburger--htx.is-active span::after {
bottom: 0;
transform: rotate(-45deg);
background: white;
}
.c-hamburger--htx.is-active span::before,
.c-hamburger--htx.is-active span::after {
transition-delay: 0s, 0.1s;
}
/* ---------------------------------------------------------End of Hamburger Button-------------------------------------------------- */
</style>
</head>
<body>
<div id="header">
<div id="headerBtnHolder">
<img onload="parallex1('image')" src="" id="image" />
<button id="fullScreenNavbt" class="c-hamburger c-hamburger--htx" onclick="toggleNavPanel('fullScreenNav','100vh','fullScreenNavbt')">
<span>toggle menu</span>
</button>
</div>
<div id="fullScreenNav">
<div>
</div>
</div>
</div>
<div id="content"></div>
<div id="footer"></div>
<script>
(function() {
"use strict";
var toggles = document.querySelectorAll(".c-hamburger");
for (var i = toggles.length - 1; i >= 0; i--) {
var toggle = toggles[i];
toggleHandler(toggle);
};
function toggleHandler(toggle) {
toggle.addEventListener( "click", function(e) {
e.preventDefault();
(this.classList.contains("is-active") === true) ? this.classList.remove("is-active") : this.classList.add("is-active");
});
}
})();
</script>
<script>
function toggleNavPanel(dropDivId, height, btnId){
var panel = document.getElementById(dropDivId), maxH= height, nav = btnId;
if(panel.style.height == maxH){
panel.style.height = "0px";
} else {
panel.style.height = maxH;
}
window.addEventListener('mouseup', function(event){
if(event.target != panel && event.target.parentNode !=panel && event.target.id != nav ){
panel.style.height = "0px";
}
});
}
</script>
<script type="text/javascript">
function parallex1(ObjectId){
var ypos, image;
function parallex () {
ypos = window.pageYOffset;
image = document.getElementById(ObjectId);
image.style.top = ypos * .6 + 'px';
}
window.addEventListener('scroll', parallex);}
</script>
</body>
</html>
Your basic problem is that on every click you're adding an eventListener so you re creating an event hell. Remove the onClick and add the event listeners only once to run your methods. Also your checks for toggling the panel are wrong. There's a span inside the button which should toggle as well.

Function toggle won't show div's inside the "toggled" div

I'm "required" to make a webpage:
In a page I want a side menu and when clicking each option it shows in the right some content, but without "loading" another page (this would be the easier way, just making a page for each "option" and then just clicking in each button would lead me to that page with the content in the right).
I found this:
<script type="text/javascript">
function toggle(IDS) {
var sel = document.getElementById('pg').getElementsByTagName('div');
for (var i=0; i<sel.length; i++) {
if (sel[i].id != IDS) { sel[i].style.display = 'none'; }
}
var status = document.getElementById(IDS).style.display;
if (status == 'block') { document.getElementById(IDS).style.display = 'none'; }
else { document.getElementById(IDS).style.display = 'block'; }
return false;
}
</script>
I just added it to the side menu and when each part is clicked it shows what I want :
<div id="sidebar2">
<div>
<h2 class="title">TEXT</h2>
<ul>
<li>TEXT</li>
<li>TEXT2</li>
</ul>
</div>
<div>
And in the content of each "option":
<div id="pg">
<div id="pg0" class="pg">
<h2 class="title">TEXT</h2>
<p><img src="images/test.png" alt=""/></p>
</div>
<div id="pg1" class="pg">
<h2 class="title">TEXT2</h2>
<p><img src="images/test2.png" alt=""/>HERE GOES THE DIV POPUP BUTTON</p>
</div>
I want a button to open a pop up image. It appears toggle() sets everything inside each div to display:none; and when I click only changes to block the outer part. But if I have a div inside, it remains hidden.
I've tried these two codes for the popup:
<div id="test">
<a href="#" class="JesterBox">
<div id="image1"><img src="bg.jpg"></div>
</a>
Image 1
With the corresponding JesterBox definition in CSS:
.JesterBox div {
visibility: hidden;
position: fixed;
top: 5%;
right: 5%;
bottom: 5%;
left: 5%;
z-index: 75;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.JesterBox div:before {
content: '';
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 74;
background-color: rgba(0, 0, 0, 0);
transition: all 0.5s ease-out;
}
.JesterBox div img {
position: relative;
z-index: 77;
max-width: 100%;
max-height: 100%;
margin-left: -9999px;
opacity: 0;
transition-property: all, opacity;
transition-duration: 0.5s, 0.2s;
transition-timing-function: ease-in-out, ease-out;
}
.JesterBox div:target { visibility: visible; }
.JesterBox div:target:before { background-color: rgba(0, 0, 0, 0.7); }
.JesterBox div:target img {
margin-left: 0px;
opacity: 1;
}
And this other:
<div class="box">
<a class="button" href="#popup1">TEXT</a>
</div>
<div id="popup1" class="overlay">
<div class="popup">
<h2>Title</h2>
<a class="close" href="#">×</a>
<div class="content">
TEXT TEXT
</div>
</div>
</div>
With its corresponding CSS:
.box {
width: 20%;
margin: 0 auto;
background: rgba(255,255,255,0.2);
padding: 35px;
border: 2px solid #fff;
border-radius: 20px/50px;
background-clip: padding-box;
text-align: center;
}
.button {
font-size: 1em;
padding: 10px;
color: #fff;
border: 2px solid #06D85F;
border-radius: 20px/50px;
text-decoration: none;
cursor: pointer;
transition: all 0.3s ease-out;
}
.button:hover {
background: #06D85F;
}
.overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
transition: opacity 500ms;
visibility: hidden;
opacity: 0;
}
.overlay:target {
visibility: visible;
opacity: 1;
}
.popup {
margin: 70px auto;
padding: 20px;
background: #fff;
border-radius: 5px;
width: 30%;
position: relative;
transition: all 5s ease-in-out;
}
.popup h2 {
margin-top: 0;
color: #333;
font-family: Tahoma, Arial, sans-serif;
}
.popup .close {
position: absolute;
top: 20px;
right: 30px;
transition: all 200ms;
font-size: 30px;
font-weight: bold;
text-decoration: none;
color: #333;
}
.popup .close:hover {
color: #06D85F;
}
.popup .content {
max-height: 30%;
overflow: auto;
}
#media screen and (max-width: 700px){
.box{
width: 70%;
}
.popup{
width: 70%;
}
}
I can't make it work. How could I make, for example, the 2nd option (the div class="box") work inside the div?
<div id="pg1" class="pg">
<h2 class="title">TEXT2</h2>
<p>
<div class="box">
<a class="button" href="#popup1">TEXT</a>
</div>
<div id="popup1" class="overlay">
<div class="popup">
<h2>Title</h2>
<a class="close" href="#">×</a>
<div class="content">
TEXT TEXT
</div>
</div>
</div>

Categories