I have two toggles (toggle-1 and toggle-2) with different contents in a header. I would like to prevent the user to have both toggles active simultaneously (otherwise they overlap).
In the code below I tried to use if statements to hide one of the toggles if the other is already opened but it does not work.
Ideally, what I would like to happen is that if toggle-1 is active and the user clicks on toggle-2, then toggle-1 would come back to its original state and toggle-2 would be now active. The same the other way around.
I am not familiar with JavaScript yet and I'd really appreciate if you could tell me what I have done wrong and how it should be done to have my ideal result
Here's the link to my CodePen if you find it easier:
https://codepen.io/fergos2/pen/NWWxgEp
var myToggle
var oneToggle = $(document).ready(function() {
$('.toggle-1').click(function() {
$('.toggle-1').toggleClass('active')
$('.toggle-1-content').toggleClass('active')
})
})
var twoToggle = $(document).ready(function() {
$('.toggle-2').click(function() {
$('.toggle-2').toggleClass('active')
$('.toggle-2-content').toggleClass('active')
})
})
if (myToggle == oneToggle) {
$(document).ready(function() {
$('toggle-2-content').hide();
})
} else if (myToggle == twoToggle) {
$('toggle-1-content').hide();
}
.container {
width: 100%;
height: 1000px;
margin: 0 auto;
background-color: #eee;
}
.wrapper {
background-color: pink;
position: relative;
display: flex;
align-items: center;
}
.toggle-1,
.toggle-2 {
display: block;
width: 20px;
height: 20px;
float: left;
cursor: pointer;
color: white;
text-align: center;
background-color: green;
margin: 10px;
}
.toggle-1.active,
.toggle-2.active {
background-color: red;
}
.toggle-1-content,
.toggle-2-content {
display: none;
}
.toggle-1-content.active,
.toggle-2-content.active {
display: block;
background-color: white;
border: 1px solid black;
position: absolute;
top: 40px;
}
.toggle-1-content.active {
left: 0;
}
.toggle-2-content.active {
left: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="wrapper">
<div class="toggle-1">1</div>
<div class="toggle-1-content">
<p>Some content 1</p>
</div>
<div class="toggle-2">2</div>
<div class="toggle-2-content">
<p>Some content 2</p>
</div>
</div>
</div>
Several issues.
Please study the code below
too many $(document.ready... and no need to store the result of such a statement
Using a data-attribute and a common class, shortens the code a lot. DRY Don't repeat yourself
I simplified the content containers CSS too
$(function() { // on page load
$('.toggle').on("click", function() { // any of the toggles
const $wrapper = $(this).closest(".wrapper");
const id = $(this).data("id");
$(this).toggleClass('active'); // toggle clicked div
const show = $(this).is(".active"); // is it active after we toggled?
$wrapper
.find(".toggle") // find all toggles
.not(this) // exclude the one we clicked
.removeClass("active"); // remove class
$wrapper.find(".content").hide(); // hide any content divs
$("#" + id).toggle(show); // show the one belonging to the clicked toggle
})
})
.container {
width: 100%;
height: 1000px;
margin: 0 auto;
background-color: #eee;
}
.wrapper {
background-color: pink;
position: relative;
display: flex;
align-items: center;
}
.toggle {
display: block;
width: 20px;
height: 20px;
float: left;
cursor: pointer;
color: white;
text-align: center;
background-color: green;
margin: 10px;
}
.active {
background-color: red;
}
.content {
display: none;
background-color: white;
border: 1px solid black;
position: absolute;
top: 40px;
}
#div1 {
left: 0;
}
#div2 {
left: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="wrapper">
<div class="toggle" data-id="div1">1</div>
<div id="div1" class="content">
<p>Some content 1</p>
</div>
<div class="toggle" data-id="div2">2</div>
<div id="div2" class="content">
<p>Some content 2</p>
</div>
</div>
</div>
Working code:
$(document).ready(function() {
$('.toggle-1').click(function() {
if ($('.toggle-2').hasClass('active')) {
// remove toggle-2 active classes
$('.toggle-2').removeClass('active');
$('.toggle-2-content').removeClass('active');
}
$('.toggle-1').toggleClass('active');
$('.toggle-1-content').toggleClass('active');
});
$('.toggle-2').click(function() {
if ($('.toggle-1').hasClass('active')) {
// remove toggle-1 active classes
$('.toggle-1').removeClass('active');
$('.toggle-1-content').removeClass('active');
}
$('.toggle-2').toggleClass('active');
$('.toggle-2-content').toggleClass('active');
});
});
Here is the link to my working version.
A few things to keep in mind:
You don't need to call $(document).ready() multiple times. There's just no reason to call it multiple times on a single page as the event is only fired once.
You need to keep track of state somehow; hence the if ($('el').hasClass('classname')) syntax. Once you handle that properly, it's easy to ensure that each element is 'reset' to its original state when the other is clicked.
Hope that helps!
toggleClass accepts a second boolean parameter that forces the type of toggle, on or off. More than that you can also target multiple elements with a single jQuery call, so use that to your advantage since the classes applied have the same name.
So you could simplify your code to
$(document).ready(function() {
$('.toggle-1').click(function() {
$('.toggle-1, .toggle-1-content').toggleClass('active');
$('.toggle-2, .toggle-2-content').toggleClass('active', false)
})
$('.toggle-2').click(function() {
$('.toggle-2, .toggle-2-content').toggleClass('active');
$('.toggle-1, .toggle-1-content').toggleClass('active', false)
})
})
.container {
width: 100%;
height: 1000px;
margin: 0 auto;
background-color: #eee;
}
.wrapper {
background-color: pink;
position: relative;
display: flex;
align-items: center;
}
.toggle-1,
.toggle-2 {
display: block;
width: 20px;
height: 20px;
float: left;
cursor: pointer;
color: white;
text-align: center;
background-color: green;
margin: 10px;
}
.toggle-1.active,
.toggle-2.active {
background-color: red;
}
.toggle-1-content,
.toggle-2-content {
display: none;
}
.toggle-1-content.active,
.toggle-2-content.active {
display: block;
background-color: white;
border: 1px solid black;
position: absolute;
top: 40px;
}
.toggle-1-content.active {
left: 0;
}
.toggle-2-content.active {
left: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="wrapper">
<div class="toggle-1">1</div>
<div class="toggle-1-content">
<p>Some content 1</p>
</div>
<div class="toggle-2">2</div>
<div class="toggle-2-content">
<p>Some content 2</p>
</div>
</div>
</div>
You can use the method "removeClass" to remove the active class from the other toggle
var oneToggle = $(document).ready(function() {
$(".toggle-1").click(function() {
$(".toggle-1").toggleClass("active")
$(".toggle-1-content").toggleClass("active")
$(".toggle-2").removeClass("active")
$(".toggle-2-content").removeClass("active")
})
})
var twoToggle = $(document).ready(function() {
$(".toggle-2").click(function() {
$(".toggle-1").removeClass("active")
$(".toggle-1-content").removeClass("active")
$(".toggle-2").toggleClass("active")
$(".toggle-2-content").toggleClass("active")
})
})
Related
let slider = document.getElementById("slider");
let rightBtn = document.getElementById("rightbutton");
let leftBtn = document.getElementById("leftbutton");
let element = document.getElementById("elementtype").innerHTML;
let celciusBoiling = document.getElementById("celciusboiling").value;
let chlorine = ["Chlorine", 100, 200];
function moveSliderRight() {
if (rightBtn.onclick) {
slider.value++;
}
}
function moveSliderLeft() {
if (leftBtn.onclick) {
slider.value--;
}
}
function main() {
moveSliderRight();
moveSliderLeft();
if (slider.value == parseInt(2)) {
element = chlorine[0];
celciusBoiling = chlorine[1];
}
}
main();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
background-color: peachpuff;
}
header {
width: 90%;
margin: 10px auto 0px;
}
header h1 {
text-align: center;
border: 1px solid black;
padding: 15px 0px;
}
.navbar {
width: 75%;
margin: 50px auto 50px;
padding: 10px 0px;
display: flex;
justify-content: space-around;
border: 1px solid black;
}
.navlinks {
border-right: 1px solid black;
width: 50%;
text-align: center;
display: block;
}
#nav3 {
border: none;
}
#intro {
margin: 0px auto 50px;
width: 40%;
text-align: center;
}
#slider {
-webkit-appearance: none;
background-color: grey;
width: 90%;
display: block;
margin: auto;
}
#slider::-webkit-slider-thumb {
cursor: pointer;
}
#slider::-moz-range-thumb {
cursor: pointer;
}
#valuetag {
text-align: center;
margin-top:25px;
}
h2 {
text-align: center;
font-size: 45px;
text-decoration: underline;
}
#display {
width: 90%;
margin-left: 50px;
margin-bottom: 50px;
font-size: 40px;
}
#display div {
display: inline-block;
width: 45%;
text-align: center;
}
span {
font-size: 15px;
}
.boiling {
margin-left: 6%;
}
.boilingpointslider {
text-align: center;
}
button {
margin: 20px 20px 20px 0px;
width: 75px;
}
<header>
<h1>Periodic Table Gases - Interative Slider</h1>
<nav>
<div class="navbar">
<div class="navlinks">Boiling Point</div>
<div class="navlinks" id="nav3">Melting Point</div>
</div>
</nav>
</header>
<div id="intro">
<p>Interact with the slider buttons to view the displayed properties held by gases, within the periodic table of elements.</p>
</div>
<h2 id="elementtype">Hydrogen</h2>
<div id="display">
<div class="boiling">
<h2>Boiling Point</h2>
<input id="celciusboiling" type="number" value="0"><span>℃</span>
<input id="fahrenboiling" type="number"><span>℉</span>
<input id="kelvinboiling" type="number"><span>K</span>
</div>
<div class="melting">
<h2>Melting Point</h2>
<input id="celciusmelting" type="number"><span>℃</span>
<input id="fahrenmelting" type="number"><span>℉</span>
<input id="kelvinmelting" type="number"><span>K</span>
</div>
</div>
<input type="range" min="0" max="9" value="0" id="slider">
<div class="boilingpointslider">
<button id="leftbutton" onclick="moveSliderLeft()">Left</button>
<button id="rightbutton" onclick="moveSliderRight()">Right</button>
</div>
I am having issues transferring a value to an input field.
Within the snippet linked their is a heading with the value hydrogen and to the bottom left their is a boiling point heading with a input field for celcius.
I'm trying to achieve a scenario whereby you move the slider along using the buttons and at each value the heading changes to a different element and the input value for just the celcius boiling point changes.
I can't get this to work though. The buttons are working to make the slider move left and right, but for whatever reason i cant get the value to appear within the input field or change the heading. I've displayed the code i have already to get the buttons to move the slider and a snippet of what i thought would allow the changes i want to take place when the slider value changes to 2. I cant get it to to work though
Thanks.
You don't show your HTML, but I presume that slider is an input (text or hidden).
The value attribute is a string, even if you assign it a number, so you need to first convert it to a integer if you want to increment or decrement it, like so:
slider.value = parseInt(slider.value)++ // or --
Note that also you are trying to parseInt(2) down in your main(), which makes no sense as 2 is already an integer.
Description: I created two buttons and two more elements (div & section).
When I click on button 1, div element will appear with background-color HotPink and/if at this moment i re-click on button 1, div element will disappear.
I also wrote a function for button 2 so that when i click on button 2, section element will appear with background-colour DarkGreen and at this moment when i click on button 2 again, section element will disappear.
I should mention that if i click on white space of body ( (document).click(event) ), both div and section elements will disapear.
Question: What function should I write to show div element when I click on button 1 and then I hide hide it when I click on button 2 or any other elements on my web page???
Demo
NOTE: I duplicated this question because I'm not interested to use any method like:
$(".button1").click(function(event){
event.stopPropagation();
if($(".div").css("display") == "none"){
$(".div").css("display","block");
$(".section").css("display","none");
}else{
$(".div").css("display","none");
}
});
$(".button2").click(function(event){
event.stopPropagation();
if($(".section").css("display") == "none"){
$(".section").css("display","block");
$(".div").css("display","none");
}else{
$(".section").css("display","none");
}
});
It would be better if you do a favour and suggest a better method instead of duplicating a line of code with different class name under different events (functions).
My codes:
HTML:
<button class="button1">
Show Div Element
</button>
<div class="div">
I am Div Element
</div>
<br><br>
<button class="button2">
Show Section Element
</button>
<section class="section">
I am Section Element
</section>
JQuery:
$(function(){
$(".button1").click(function(event){
event.stopPropagation();
if($(".div").css("display") == "none"){
$(".div").css("display","block");
}else{
$(".div").css("display","none");
}
});
$(".button2").click(function(event){
event.stopPropagation();
if($(".section").css("display") == "none"){
$(".section").css("display","block");
}else{
$(".section").css("display","none");
}
});
$(document).click(function(){
$(".div").css("display","none");
$(".section").css("display","none");
});
});
The easiest way would be to start .click functions for both button 1 & 2 with:
.css("display","none");
function hidding the other element, like this:
$(".button1").click(function(event){
$(".section").css("display","none");
event.stopPropagation();
if($(".div").css("display") == "none"){
$(".div").css("display","block");
}else{
$(".div").css("display","none");
}
});
$(".button2").click(function(event){
$(".div").css("display","none");
event.stopPropagation();
if($(".section").css("display") == "none"){
$(".section").css("display","block");
}else{
$(".section").css("display","none");
}
});
Solution without JQuery... But you can use it if you really want to.
const $ = document.querySelector.bind(document);
const $$ = document.querySelectorAll.bind(document);
$('.button1').addEventListener('click', ()=>{
toggle('div')
});
$('.button2').addEventListener('click', ()=>{
toggle('section')
});
function toggle(element){
if($('.show')){
Array.from($$('.show')).forEach((ele) => {
ele.classList.remove('show');
});
}
$(element).classList.add('show');
}
html, body {
background-color: #fafafa;
width: 100%;
height: 100%;
padding: 12px;
margin: 0;
}
.button1 {
background-color: pink;
position: relative;
display: inline-block;
padding: 8px;
border: none;
margin: 0 0 6px 0;
cursor: pointer;
}
.div {
background-color: hotpink;
display: none;
width: 160px;
height: 160px;
}
.button2 {
background-color: green;
position: relative;
display: inline-block;
padding: 8px;
color: white;
border: none;
margin: 0 0 6px 0;
cursor: pointer;
}
.section {
background-color: darkgreen;
display: none;
width: 160px;
height: 160px;
color: white;
}
.show {
display: block;
}
<button class="button1">
Show Div Element
</button>
<div class="div">
I am Div Element
</div>
<br>
<br>
<button class="button2">
Show Section Element
</button>
<section class="section">
I am Section Element
</section>
This solution relies on event bubbling, so it might break if other handlers stop propagation.
Also note that it currently relies on provided html structure, but that can be tweaked easy enough.
$(document).click(function(e) {
$elem = $(e.target)
// If the element is visible we shouldn't open it again
needToggle = $elem.is('button') && !$elem.next().hasClass("open")
$(".open").removeClass("open") // Remove all open elements
if (needToggle) {
$elem.next().toggleClass("open")
}
})
html,
body {
background-color: #fafafa;
width: 100%;
height: 100%;
padding: 12px;
margin: 0;
}
.button1 {
background-color: pink;
position: relative;
display: inline-block;
padding: 8px;
border: none;
margin: 0 0 6px 0;
cursor: pointer;
}
.div {
background-color: hotpink;
display: none;
width: 160px;
height: 160px;
}
.button2 {
background-color: green;
position: relative;
display: inline-block;
padding: 8px;
color: white;
border: none;
margin: 0 0 6px 0;
cursor: pointer;
}
.section {
background-color: darkgreen;
display: none;
width: 160px;
height: 160px;
color: white;
}
.open {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="button1">
Show Div Element
</button>
<div class="div">
I am Div Element
</div>
<br><br>
<button class="button2">
Show Section Element
</button>
<section class="section">
I am Section Element
</section>
I have this flexible layout and some JS https://jsfiddle.net/7k8t3xgc/3/
<div class="window">
<div class="left">
<div class="optional">optional content</div>
</div>
<div class="right">
<div class="wordpool"></div>
<div class="category"></div>
</div>
</div>
The .wordpool element is filled with some words that need to be moved to the .category element by clicking on them.
What is happening now, is that the .window element is shrinking in width when you click the words. Is there a way to prevent this behaviour? Only way I can think of is to calculate wordpools width on render and set it into a style attribute, but it has its drawbacks with responsiveness.
I can't remove the flex functionality, because both left (optional) and right panels need to be same width and centered.
I can't use static width as it needs to be responsive.
It can't be something like .window { width: 90%; } because of short content looking silly on wide screens.
Both left and right content changes between pages in my app (think of a quiz or Google Forms - can be text, can be images, checkboxes, radiobuttons etc.) but the HTML template is the same.
As you want it to be dynamic, based on the actual text width on load, add this line to your script
$(".window").css('min-width', $(".window").width() + 'px');
Updated fiddle
Instead of monitoring the resize event for smaller screens, you can do like this instead
Note, the width: 100% needs to be set using the script, if set in CSS, the calculation will be wrong
$(".window").css({'max-width':$(".window").width() + 'px','width':'100%'});
Updated fiddle 2
Just to provide another solution, that may or not be what you want:
Don't change the elements from container, just have them on both containers, and toggle the opacity.
You can rearrange them using flexbox and order
var buttons = [{
name: "lorem"
},
{
name: "ipsum"
},
{
name: "dolor"
},
{
name: "sit"
},
{
name: "amet"
}
];
$(document).ready(function() {
for (b of buttons) {
$('.wordpool').append($("<span>", {
class: "word",
id: b.name
}).html(b.name));
$('.category').append($("<span>", {
class: "word hidden",
id: b.name
}).html(b.name));
}
$(".wordpool").on("click", "span", function() {
$(this).toggleClass('hidden');
$(".category #" + $(this).attr('id')).toggleClass('hidden');
});
$(".category").on("click", "span", function() {
$(this).toggleClass('hidden');
$(".wordpool #" + $(this).attr('id')).toggleClass('hidden');
});
$("body").on("click", ".showoptional", function() {
$(".left").toggle();
});
});
html,
body {
height: 100%;
margin: 0;
}
.wrapper {
box-sizing: border-box;
width: 100%;
height: 100%;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
background: #f4efdc;
}
.showoptional {
position: absolute;
top: 5px;
left: 5px;
}
.window {
background: #fff;
box-shadow: 0 0 10px #ccc;
display: flex;
}
.left,
.right {
padding: 20px;
flex: 1 0 0px;
}
.left {
display: none;
}
.optional {
background: #eee;
text-align: center;
padding: 50px 0;
}
.word {
display: inline-block;
margin: 2px 5px;
padding: 3px 5px;
border: 1px solid #ddd;
cursor: pointer;
}
.hidden {
opacity: 0;
order: 99;
}
.wordpool {
text-align: center;
display: flex;
}
.category {
margin-top: 10px;
border: 1px solid #ccc;
min-height: 60px;
}
.category .word {
display: block;
text-align: center;
margin: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<input type="button" class="showoptional" value="Trigger optional content" />
<div class="window">
<div class="left">
<div class="optional">optional content</div>
</div>
<div class="right">
<div class="wordpool"></div>
<div class="category"></div>
</div>
</div>
</div>
I have two divs with same class. If I scroll one div the other divs scroll comes to 0. I am able to achieve this with .prop() property easily. But when I use .animate() the occurrence just happens once and then it stops working(Commented the code in my example snippet) . What I want is the scroll when comes to zero should animate i.e the scroll comes to 0 with a animation like its showing with .animate().
Note: Classes of divs will be same and there can be more divs too.
Here is the code I have tried, please tell me where I am wrong.
$(document).ready(function() {
$('.swipe_div').scroll(function() {
// $(this).siblings(".swipe_div").animate({scrollLeft: 0},100);
$(this).siblings(".swipe_div").prop({
scrollLeft: 0
});
});
});
body,
html {
width: 100%;
height: 100%;
background-color: green;
padding: 0;
margin: 0;
}
.swipe_div {
display: block;
float: left;
width: 100%;
height: 100px;
overflow-x: scroll;
background-color: white;
}
.content,
.operation,
.swipe_container {
display: block;
float: left;
height: 100%;
}
.swipe_container {
width: 150%;
}
.content {
display: flex;
align-items: center;
justify-content: flex-end;
flex-direction: row;
text-align: right;
font-size: 30pt;
width: 67%;
background-color: grey;
}
.operation {
width: 33%;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="swipe_div">
<div class="swipe_container">
<div class="content">
>
</div>
<div class="operation">
</div>
</div>
</div>
<div class="swipe_div">
<div class="swipe_container">
<div class="content">
>
</div>
<div class="operation">
</div>
</div>
</div>
When you're animating scrollLeft you're activating scroll() on the sibling, which is trying to animate scroll on the div you're actively scrolling. So you need to mark when you start scrolling and throttle() all subsequent calls on scroll() until you're done scrolling.
trailing:true calls it one more time after it hasn't been called for throttle_interval (250 in this example), turning scrolling marker back to false:
$(document).ready(function() {
var scrolling;
$('.swipe_div').scroll(_.throttle(function() {
if (!scrolling) {
scrolling = true;
$(this).siblings(".swipe_div").animate({scrollLeft: 0},150);
} else {
scrolling = false;
}
}, 250, {leading:true,trailing:true}));
});
body,
html {
width: 100%;
height: 100%;
background-color: green;
padding: 0;
margin: 0;
}
.swipe_div {
display: block;
float: left;
width: 100%;
height: 100px;
overflow-x: scroll;
background-color: white;
}
.content,
.operation,
.swipe_container {
display: block;
float: left;
height: 100%;
}
.swipe_container {
width: 150%;
}
.content {
display: flex;
align-items: center;
justify-content: flex-end;
flex-direction: row;
text-align: right;
font-size: 30pt;
width: 67%;
background-color: grey;
}
.operation {
width: 33%;
background-color: red;
}
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="swipe_div">
<div class="swipe_container">
<div class="content">
>
</div>
<div class="operation">
</div>
</div>
</div>
<div class="swipe_div">
<div class="swipe_container">
<div class="content">
>
</div>
<div class="operation">
</div>
</div>
</div>
I tested it for a bit and actually discovered a small glitch/limitation: the throttle interval has to be smaller than the animation time. If it is not, the animation will outlast the throttle interval and trigger, in turn, the closing animation for the original scrolled element.
But this is web (impossible is nothing): if and when your animation has to be longer than the throttle interval, you will have to mark the initial element with a class that will exclude it from being animated. The class will be removed using a timeout on completion of animate, equal to the throttle interval:
$(document).ready(function() {
var scrolling;
$('.swipe_div').scroll(_.throttle(function() {
if (!scrolling) {
scrolling = true;
$(this).addClass('original');
$(this).siblings(".swipe_div:not(.original)").animate(
{scrollLeft:0},
250,
function(){
setTimeout(function() {
$('.swipe_div').removeClass('original')
}, 150)
}
);
} else {
scrolling = false;
}
}, 150, {leading:true,trailing:true}));
});
I want a full width panel to slide down from the top of the browser, that will display my contact details, along with social links etc:
$(document).ready(function() {
$("#flip").click(function() {
$("#panel").slideToggle();
});
});
#flip {
padding: 5px;
width: 300px;
text-align: center;
background-color: #e5eecc;
border: solid 1px #c3c3c3;
}
#panel {
padding: 50px;
display: none;
width: 100%;
height: 200px;
z-index: 5000;
background-color: black;
}
.f {
position: static;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="panel">Hello world!</div>
<div id="flip">
<span class="f">MENU</span>
</div>
This works a treat, but how can I specify different times for slide up and slidedown?
You can store duration of animation in variable and use it. In function of callback of slideToggle() change duration.
var duration = 500;
$("#flip").click(function() {
$("#panel").slideToggle(duration, function(){
duration = $(this).is(":visible") ? 2000 : 500;
});
});
var duration = 500;
$("#flip").click(function() {
$("#panel").slideToggle(duration, function(){
duration = $(this).is(":visible") ? 2000 : 500;
});
});
#flip {
width: 300px;
text-align: center;
background-color: #e5eecc;
border: solid 1px #c3c3c3;
}
#panel {
display: none;
width: 100%;
height: 150px;
background-color: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="panel">Hello world!</div>
<div id="flip">
<span class="f">MENU</span>
</div>
EDIT
I have edit my answer to reflect the change in the question.
Use slideDown() and slideUp() instead.
CODEPEN
http://codepen.io/alexincarnati/pen/PWOPjY
In case you want to add different durations to sliding up and down in jQuery then you can simply add a flag and check if the menu is opened or not and then use slideDown() and slideUp() as methods.
That way you could add different durations to the slide.
$(document).ready(function() {
var menuOpened = false;
$("#flip").click(function() {
if (menuOpened === false) {
$("#panel").slideDown(1000, function() {
menuOpened = true;
});
} else {
$("#panel").slideUp(700, function() {
menuOpened = false;
});
}
});
});
Simply just add the time as a parameter to the slideToggle method.
You can see in the docs this:
slideToggle( [duration ] [, complete ] )
duration (default: 400)
Type: Number or String
A string or number determining how long the animation will run.
complete
Type: Function()
A function to call once the animation is complete, called once per matched element.
$(document).ready(function() {
$("#flip").click(function() {
$("#panel").slideToggle(3000);
});
});
#flip {
padding: 5px;
width: 300px;
text-align: center;
background-color: #e5eecc;
border: solid 1px #c3c3c3;
}
#panel {
padding: 50px;
display: none;
width: 100%;
height: 200px;
z-index: 5000;
background-color: black;
}
.f {
position: static;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="panel">Hello world!</div>
<div id="flip">
<span class="f">MENU</span>
</div>
You can read more in the official documentation here.
UPDATE:
If you want to have different durations for slideUp() and slideDown() methods you can do something like this:
$(document).ready(function() {
var check_state = false;
$("#flip").click(function() {
if (check_state === false) {
$("#panel").stop().slideDown(3000);
check_state = true;
} else {
$("#panel").stop().slideUp(1500);
check_state = false;
}
});
});
#flip {
padding: 5px;
width: 300px;
text-align: center;
background-color: #e5eecc;
border: solid 1px #c3c3c3;
}
#panel {
padding: 50px;
display: none;
width: 100%;
height: 200px;
z-index: 5000;
background-color: black;
}
.f {
position: static;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="panel">Hello world!</div>
<div id="flip">
<span class="f">MENU</span>
</div>
You can specify the time in the first parameter of the function slideToggle:
$("#panel").slideToggle(4000);
You can read about .slideToggle() on jquery documentation
As it say the slideToggle() function accept two parameters:
.slideToggle( [duration ] [, complete ] )
The first is for the duration (in millisecond) and the second is the callback after the animation is complete
$(document).ready(function() {
$("#flip").click(function() {
$("#panel").slideToggle(5000 /* Here is the duration of the animation in MS */, function() {
//Do what you want here
});
});
});
#flip {
padding: 5px;
width: 300px;
text-align: center;
background-color: #e5eecc;
border: solid 1px #c3c3c3;
}
#panel {
padding: 50px;
display: none;
width: 100%;
height: 200px;
z-index: 5000;
background-color: black;
}
.f {
position: static;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="panel">Hello world!</div>
<div id="flip">
<span class="f">MENU</span>
</div>