How to create a toggle button to switch between panels - javascript

In my application I have 2 toggle buttons and 3 panels. Button1 switches between panel 1 and 2. And button2 switches between panel 1 and 3. I could make it work some how by giving display: none; property to div panels. but once it only works once for each button and then it makes all sub divs to display: none;
Have a look at the sample please:
$(function () {
$("button.panel2").on("click", function() {
var visibleObj = $('.mainSection div:visible');
if ($("div.panel2").css("display") == "none") {
var inVisibleObj = $("div.panel2")
}
else {
var inVisibleObj = $("div.panel1")
}
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
})
});
$("button.panel3").on("click", function() {
var visibleObj = $('.mainSection div:visible');
if ($("div.panel3").css("display") == "none") {
var inVisibleObj = $("div.panel3")
}
else {
var inVisibleObj = $("div.panel1")
}
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
})
});
});
div.app {
margin:50px auto;
width: 400px;
height: 400px;
border-radius:10px;
overflow: hidden;
position: relative;
}
div.app > .blur {
width: 100%;
height: 100%;
background: url(http://goo.gl/0VTd9W);
-webkit-filter: blur(5px);
}
div.mainSection, div.dashboard{
position: absolute;
left: 0px;
text-align:center;
color:#fff;
font-size:20px;
}
div.mainSection{
width:100%;
height:85%;
background:rgba(0,0,0,0.5);
top:0;
}
div.dashboard{
width:100%;
height:15%;
background:rgba(255,0,0,0.5);
bottom:0;
}
div.mainSection > .panel1,
div.mainSection > .panel2,
div.mainSection > .panel3 {
width: 100%;
Height: 100%;
Background: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0px;
top: 0px;
}
div.mainSection > .panel3 > p{
margin-top:80px;
}
.grid-button {
background: none;
border: none;
padding: 3px;
width: 100%;
}
.grid {
display: inline-block;
height: 4px;
position: relative;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid:after, .grid:before {
content: '';
position: absolute;
background-color: #FFF;
display: inline-block;
height: 4px;
left: 0;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid.open {
background-color: #FFF;
}
.grid.open:after {
top: 10px;
}
.grid.open:before {
top: -10px;
}
.grid.close {
background-color: transparent;
transform: scale(0.9);
}
.grid.close:after, .grid.close:before {
top: 0;
transform-origin: 50% 50%;
}
.grid.close:before {
transform: rotate(135deg);
}
.grid.close:after {
transform: rotate(45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="app">
<div class="blur"></div>
<div class="mainSection">
<div class="panel1">
<div>panel1</div>
<div>panel1</div>
</div>
<div class="panel2" style="display: none;">
<div>panel2</div>
</div>
<div class="panel3" style="display: none;">
<p>Panel3</p>
<div>panel3</div>
<div>panel3</div>
</div>
</div>
<div class="dashboard">
<button class="panel2">button1</button>
<button class="panel3">button2</button>
</div>
</div>
As you can see, each panel has some inner divs. the first time, it shows all inner divs. but once you switch between panels, it will not show inner divs inside. I tried to disappear the panels div only but it seems it does it for every div within that panel.
So any idea to keep make it work so switching between panels will not affect the inner divs?

You need to change your javascript in this way:
$(function () {
$("button.panel2").on("click", function() {
var visibleObj = $('.mainSection > div:visible');
if ($("div.panel2").css("display") == "none") {
var inVisibleObj = $("div.panel2")
}
else {
var inVisibleObj = $("div.panel1")
}
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
});
});
$("button.panel3").on("click", function() {
var visibleObj = $('.mainSection > div:visible');
if ($("div.panel3").css("display") == "none") {
var inVisibleObj = $("div.panel3")
}
else {
var inVisibleObj = $("div.panel1")
}
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
})
});
});
The problem is in your selector $('.mainSection div:visible');. This select also the child div and when you try to show the correct panel the child div are hidden. If you use $('.mainSection > div:visible'); you get only the direct child divs.

Related

Why I have to click 2 times to run this function?

This is the code i'm working on, and i don't know why everytime that i refresh the page i need to click 2 times to open the menu. Once i click the second time all works correctly.
This is the html of the button:
var x = document.getElementById("overlay-menu");
x.style.height = "0%";
function showMenu() {
var x = document.getElementById("overlay-menu");
if (x.style.height === "0%") {
x.style.height = "100%";
} else {
x.style.height = "0%";
}
}
.overlay-menu {
width: 100%;
height: 0%;
padding: 0;
margin: 0;
background-color: #ffffff;
z-index: 10000;
position: fixed;
color: #0A0A0A;
overflow: hidden;
display: block;
transition: .5s cubic-bezier(.55, .03, .26, 1.01);
}
.nav-menu-text {
width: fit-content;
height: fit-content;
margin: 0;
padding: 0;
color: #EB761D;
font-size: 15px;
position: relative;
top: 2.8em;
cursor: pointer;
}
<p class="nav-menu-text" onclick="showMenu()">MENU</p>
<div class="overlay-menu" id="overlay-menu">
<!-- code of the menu -->
</div>
x.style.height is probably not "0%" when your code runs, try changing the condition from:
if (x.style.height === "0%") {
to
if (x.style.height !== "100%") {

Using .is() target Off-canvas Nav Click

I'm creating an off-canvas nav that closes on three conditions:
The user toggles the nav button
the user clicks a link inside the nav
the user clicks anywhere but the nav when the nav is open.
I've got the first two conditions working but not the third. Below is my code. What I'm trying to accomplish is essentially the following:
check for a click on the body and if that click is the (in this case) .pageContainer run a second check to see if the nav has the class "showMenu" and the flag is == true
$(document).ready(function() {
var button = $('.button');
var ocn = $('.ocn');
var test = $('.test');
var flag = false;
//toggle menu using just the button
button.click(function() {
if ( flag == false ) {
ocn.addClass('showMenu');
flag = true;
} else {
ocn.removeClass('showMenu');
flag = false;
}
});
//close the menu clicking on a link
test.click(function() {
ocn.removeClass('showMenu');
flag = false;
});
//close menu when click off canvas
/*
$('body').on('click', '.pageContainer', function(e) {
if( ocn.hasClass('showMenu') && flag == true) {
ocn.removeClass('showMenu');
flag = false;
}
});
*/
});
* {
padding: 0;
margin: 0;
}
.ocn {
position: absolute;
left: -300px;
top: 0;
width: 300px;
height: 100vh;
background-color: #ccc;
transition: left .2s ease;
z-index: 2;
border: 1px solid;
}
.showMenu {
left: 0px;
}
.pageContainer {
height: 500px;
width: 1000px;
border: 1px solid;
display: block;
margin: 0 auto;
}
.button {
height: 40px;
width: 40px;
border: 1px dashed;
display: block;
position: relative;
left: 400px;
cursor: pointer;
}
.test {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="ocn">
<p class="test">here is some text for the menu</p>
</div>
<div class="pageContainer">
<div class="button"></div>
</div>
You can use the e.target property to compare what was clicked. Similar to this:
if(e.target == pageContainer[0])
You can now apply the required logic when .pageContainer was clicked.
$(document).ready(function() {
var pageContainer = $('.pageContainer');
var button = $('.button');
var ocn = $('.ocn');
var test = $('.test');
var flag = false;
//toggle menu using just the button
button.click(function() {
if (flag == false) {
ocn.addClass('showMenu');
flag = true;
} else {
ocn.removeClass('showMenu');
flag = false;
}
});
//close the menu clicking on a link
test.click(function() {
ocn.removeClass('showMenu');
flag = false;
});
//close menu when click off canvas
$('body').on('click', '.pageContainer', function(e) {
if (e.target == pageContainer[0]) {
//console.log('pageContainer was clicked')
if (ocn.hasClass('showMenu') && flag == true) {
ocn.removeClass('showMenu');
flag = false;
}
};
});
});
* {
padding: 0;
margin: 0;
}
.ocn {
position: absolute;
left: -300px;
top: 0;
width: 300px;
height: 100vh;
background-color: #ccc;
transition: left .2s ease;
z-index: 2;
border: 1px solid;
}
.showMenu {
left: 0px;
}
.pageContainer {
height: 500px;
width: 1000px;
border: 1px solid;
display: block;
margin: 0 auto;
}
.button {
height: 40px;
width: 40px;
border: 1px dashed;
display: block;
position: relative;
left: 400px;
cursor: pointer;
}
.test {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="ocn">
<p class="test">here is some text for the menu</p>
</div>
<div class="pageContainer">
<div class="button"></div>
</div>

How to make this animation properly with jQuery

I am trying to make an animation, you can see my efforts at jsfiddle. And here is the code I've used:
/* JavaScript: */
var app = function () {
var self = this;
var allBoxes = $('.box');
var shadow = $('#shadow');
var busy = false;
self.init = function () {
self.events();
};
self.getBoxLeftPosition = function(id)
{
var left = 100;
if (id == 'box2')
{
left = 300;
} else if (id == 'box3')
{
left = 500;
} else if (id == 'box4')
{
left = 700;
}
return left;
};
self.events = function () {
allBoxes.on('hover mousemove', function(event) {
event.stopPropagation();
var currentBox = $(this);
if (currentBox.hasClass('inactive') && !busy)
{
busy = true;
currentBox.removeClass('inactive').addClass('active').animate({
left: '-=30',
width: 260
}, 400, function () {
busy = false;
});
shadow.fadeIn(400);
}
});
$('body').mousemove(function(event) {
var currentBox = $('.active');
var leftValue = self.getBoxLeftPosition(currentBox.attr('id'));
if (currentBox.length > 0)
{
currentBox.stop();
currentBox.animate({
left: leftValue,
width: 200
}, 300, 'swing', function () {
currentBox.removeClass('active').addClass('inactive');
}, 300);
shadow.fadeOut(300);
}
});
};
return self;
};
var main = new app();
main.init();
/* CSS: */
html, body {
margin: 0;
}
.box {
position: absolute;
top: 120px;
width: 200px;
height: 420px;
}
.box div {
text-align: center;
color: white;
position: absolute;
top: 200px;
left: 0;
right: 0;
font-size: 25px;
font-weight: bold;
}
#box1 {
left: 100px;
background: pink;
}
#box2 {
left: 300px;
background: skyblue;
}
#box3 {
left: 500px;
background: orange;
}
#box4 {
left: 700px;
background: lightgreen;
}
#shadow {
display: none;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url('https://lh6.googleusercontent.com/Vz0GTzpQVaxmlIvvGgg64CSxcYBbHzu7gMQERduJ4qjU5HAg8KfisFFQvIqvKL5Vn7LIy6HZ=w1920-h916');
z-index: 10;
}
.inactive {
z-index: 5;
}
.active {
z-index: 20;
}
<!-- HTML: -->
<div id="box1" class="box inactive">
<div id="copy1">Copy 1</div>
</div>
<div id="box2" class="box inactive">
<div id="copy2">Copy 2</div>
</div>
<div id="box3" class="box inactive">
<div id="copy3">Copy 3</div>
</div>
<div id="box4" class="box inactive">
<div id="copy4">Copy 4</div>
</div>
<div id="shadow"></div>
Here is what I am trying to achieve in words: I have 4 boxes and whenever a user hovers over one of them that box needs to expand a little and everything else needs to be grayed out and whenever the mouse leaves the box it needs to go back to it's original state.
In my jsfiddle I got it working to a point but it's buggy.
take a look at this JSFiddle
$('.box').hover(function(){
$(this).siblings().addClass('inactive');
}, function(){
$(this).siblings().removeClass('inactive');
});
tried to do it with pure css but sadly there's no such thing as prev sibling selector in css. Its kinda jumpy because of z-index getting immediately change on hover.
You can achieve the same effect even with CSS
$(document).on('mouseenter', '.item', function(e){
var me = $(this);
$('.item').not(this).addClass('greyed');
});
$(document).on('mouseleave', '.item', function(e){
$('.item').removeClass('greyed');
});
ul,li{
list-style:none;padding:0;margin:0;
}
ul{
width:400px;
}
li, .item {
width:100px;
height:100px;
}
li {
float:left;
position:relative;
}
.item {
background-color: #eee;
border:1px solid #ccc;
position:absolute;
z-index:1;
-webkit-transition:all 0.3s ease-in-out;
}
.item:hover {
width:110px;
z-index:2;
}
.red{
background: red;
}
.pink{
background: pink;
}
.blue{
background: blue;
}
.yellow{
background: yellow;
}
.greyed{
-webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
filter: grayscale(100%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<ul>
<li>
<div class="item red"></div>
</li>
<li>
<div class="item blue"></div>
</li>
<li>
<div class="item yellow"></div>
</li>
<li>
<div class="item pink"></div>
</li>
</ul>
Here is what I did.
First, I found that the background image in your css is not a valid resource, so I replaced it with regular background color (it's transparent black, you may want to adjust it).
Second, I changed allBoxes.on('hover mousemove' to allBoxes.on('mouseover', and $('body').mousemove to allBoxes.on('mouseout'.
Third, I removed the $busy flag tracking.
Fourth, I changed var currentBox = $('.active'); to var currentBox = $(event.target);.
var app = function () {
var self = this;
var allBoxes = $('.box');
var shadow = $('#shadow');
var busy = false;
self.init = function () {
self.events();
};
self.getBoxLeftPosition = function(id)
{
var left = 100;
if (id == 'box2')
{
left = 300;
} else if (id == 'box3')
{
left = 500;
} else if (id == 'box4')
{
left = 700;
}
return left;
};
self.events = function () {
allBoxes.on('mouseover', function(event) {
event.stopPropagation();
var currentBox = $(this);
if (currentBox.hasClass('inactive') && !busy)
{
//busy = true;
currentBox.removeClass('inactive').addClass('active').animate({
left: '-=30',
width: 260
}, 400, function () {
//busy = false;
});
shadow.fadeIn(400);
}
});
allBoxes.on('mouseout', function(event) {
var currentBox = $(event.target);
var leftValue = self.getBoxLeftPosition(currentBox.attr('id'));
if (currentBox.length > 0)
{
currentBox.stop();
currentBox.animate({
left: leftValue,
width: 200
}, 300, 'swing', function () {
currentBox.removeClass('active').addClass('inactive');
}, 300);
shadow.fadeOut(300);
}
});
};
return self;
};
var main = new app();
main.init();
html, body {
margin: 0;
}
.box {
position: absolute;
top: 120px;
width: 200px;
height: 420px;
}
.box div {
text-align: center;
color: white;
position: absolute;
top: 200px;
left: 0;
right: 0;
font-size: 25px;
font-weight: bold;
}
#box1 {
left: 100px;
background: pink;
}
#box2 {
left: 300px;
background: skyblue;
}
#box3 {
left: 500px;
background: orange;
}
#box4 {
left: 700px;
background: lightgreen;
}
#shadow {
display: none;
position: absolute;
left: 0;
top: 0;
width: 1000px;
height: 600px;
/*background: url('https://lh6.googleusercontent.com/Vz0GTzpQVaxmlIvvGgg64CSxcYBbHzu7gMQERduJ4qjU5HAg8KfisFFQvIqvKL5Vn7LIy6HZ=w1920-h916');*/
background-color: rgba(0,0,0,0.5); /* transparent black */
z-index: 10;
}
.inactive {
z-index: 5;
}
.active {
z-index: 20;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="box1" class="box inactive">
<div id="copy1">Copy 1</div>
</div>
<div id="box2" class="box inactive">
<div id="copy2">Copy 2</div>
</div>
<div id="box3" class="box inactive">
<div id="copy3">Copy 3</div>
</div>
<div id="box4" class="box inactive">
<div id="copy4">Copy 4</div>
</div>
<div id="shadow"></div>

Stop lines from wrapping when using jquery animate

I have this fiddle set up: https://jsfiddle.net/xwb9594m/
As you can see when the slide menu gets toggled off, the content wraps as the menu shrinks. I'm trying to just get it to slide away off the side of the screen cleanly.
This is my JS:
$(document).ready(function() {
var menuBtn = $('.video-search-button'),
menu = $('.video-search-menu'),
close = $('.video-search-menu .close');
menuBtn.click(function(){
menu.animate({width: 'toggle'});
});
close.click(function(){
menu.animate({width: 'toggle'});
});
});
and my SCSS:
.video-search-menu {
display: none;
position: fixed;
top: 0;
right: 0;
width: auto;
height: 100%;
overflow: hidden;
background: #24637e;
background: rgba(36, 99, 126, 0.9);
color: #fff;
z-index: 101;
&-wrapper {
position: relative;
padding: 180px 50px 0 50px;
}
.close {
position: absolute;
width: 40px;
height: 40px;
top: 15px;
left: 15px;
z-index: 9999;
cursor: pointer;
&:before, &:after {
content: '';
position: absolute;
width: 100%;
top: 50%;
height: 2px;
background: #ffffff;
transform: rotate(45deg);
}
&:after {
transform: rotate(-45deg);
}
}
}
Add a CSS rule
p{
overflow: hidden;
white-space: nowrap;
}
I updated your jsFiddle
Or copy the code below:
$(document).ready(function() {
var menuBtn = $('.video-search-button'),
menu = $('.video-search-menu'),
close = $('.video-search-menu .close');
var right = (1 - menu.width()) - 1;
menu.css('right', right);
menuBtn.click(function(){
menu.animate({right: 0}).show();
});
close.click(function(){
menu.animate({right: right});
});
});
Update: Close menu on clicking again on the button
jsFiddle
Or copy the code below:
$(document).ready(function() {
var menuBtn = $('.video-search-button'),
menu = $('.video-search-menu'),
close = $('.video-search-menu .close');
var right = (1 - menu.width()) - 1;
menu.css('right', right);
menuBtn.click(function(){
if(menu.is(':visible')) {
close.trigger('click');
}
else {
menu.animate({right: 0}).show();
}
});
close.click(function(){
menu.animate({right: right}, function() {
menu.hide();
});
});
});
Update 2:
You can also save some lines of code for your close-"icon":
jsFiddle

creating toggle buttons to switch between div panels

My web application is made of various panels and a dashboard that has buttons to access each panel. So each button is a toggle between the purposed panel and the main panel.
For example, if we have 3 panels, panel1 is the default one and two buttons to toggle between other two panels the the default one:
button.panel2 should switch between panel1 and panel2
button.panel3 should switch between panel1 and panel3
I have almost achieved it but my code shows both panel2 and panel3 overlapping.
$(function () {
$(".panel2").on("click", function() {
var visibleObj = $('.mainSection div:visible');
var inVisibleObj = $('.mainSection div:hidden');
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
});
});
$(".panel3").on("click", function() {
var visibleObj = $('.mainSection div:visible');
var inVisibleObj = $('.mainSection div:hidden');
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
});
});
});
div.app {
margin:50px auto;
width: 400px;
height: 400px;
border-radius:10px;
overflow: hidden;
position: relative;
}
div.app > .blur {
width: 100%;
height: 100%;
background: url(http://goo.gl/0VTd9W);
-webkit-filter: blur(5px);
}
div.mainSection, div.dashboard{
position: absolute;
left: 0px;
text-align:center;
color:#fff;
font-size:20px;
}
div.mainSection{
width:100%;
height:85%;
background:rgba(0,0,0,0.5);
top:0;
}
div.dashboard{
width:100%;
height:15%;
background:rgba(255,0,0,0.5);
bottom:0;
}
div.mainSection > .panel1,
div.mainSection > .panel2,
div.mainSection > .panel3 {
width: 100%;
Height: 100%;
Background: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0px;
top: 0px;
}
div.mainSection > .panel3 > p{
margin-top:80px;
}
.grid-button {
background: none;
border: none;
padding: 3px;
width: 100%;
}
.grid {
display: inline-block;
height: 4px;
position: relative;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid:after, .grid:before {
content: '';
position: absolute;
background-color: #FFF;
display: inline-block;
height: 4px;
left: 0;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid.open {
background-color: #FFF;
}
.grid.open:after {
top: 10px;
}
.grid.open:before {
top: -10px;
}
.grid.close {
background-color: transparent;
transform: scale(0.9);
}
.grid.close:after, .grid.close:before {
top: 0;
transform-origin: 50% 50%;
}
.grid.close:before {
transform: rotate(135deg);
}
.grid.close:after {
transform: rotate(45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="app">
<div class="blur"></div>
<div class="mainSection">
<div class="panel1">Panel1</div>
<div class="panel2" style="display: none;">Panel2</div>
<div class="panel3" style="display: none;"><p>Panel3</p></div>
</div>
<div class="dashboard">
<button class="panel2">button1</button>
<button class="panel3">button2</button>
</div>
</div>
So I want to make button1 responsible to switch between panel 1 and 2. and button2 to switch between panel 1 and 3.
Any idea how to do it?
I think you need something like this. just these jquery code will be useful.
var currentPanel = 1;
$('.panelControlBtn').on("click", function() {
var ID = $(this).attr('data-id');
if (ID != currentPanel) {
$(".panel").fadeOut('fast', function() {
$("#panel" + ID).fadeIn('fast');
});
currentPanel = ID;
}
});
How about this? https://jsfiddle.net/oez0488h/53/
$("button.panel2").on("click", function() {
var visibleObj = $('.mainSection div:visible');
if ($("div.panel2").css("display") == "none") {
var inVisibleObj = $("div.panel2")
}
else {
var inVisibleObj = $("div.panel1")
}
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
})
});
$("button.panel3").on("click", function() {
var visibleObj = $('.mainSection div:visible');
if ($("div.panel3").css("display") == "none") {
var inVisibleObj = $("div.panel3")
}
else {
var inVisibleObj = $("div.panel1")
}
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
})
});

Categories