Toggle a function on click - javascript

I am trying to turn on and turn off a function on click - toggle a function.
I want .fly element to not disappear, only the animation should stop and return to its origin. When the button is clicked, the animation should stop. When it's clicked again, the animation starts again.
HTML
<div class="hobbie-box">
<div class="circle-image">
<i id="travel" class="fa fa-plane fly"></i>
</div>
<div class="circle-text">
<p>Travel industry</p>
</div>
</div>
<button type="button" class="btn toggle-effects">Turn off effects</button>
Javascript
var flyplane = function(){
setInterval(function() {
$fly.animate({
right: '-=50',
bottom: '+=50'
}, 2000, function() {
$fly.removeAttr("style");
});
}, 2000);
};
flyplane();
$(".toggle-effects").on("click", function () {
$(this).text(function (i, text) {
return text === "Turn off effects" ? "Turn on effects" : "Turn off effects";
})
$("#travel").toggle($fly);
}); //end of button click

There is a live example.
Please refer to my codepen
<div class="hobbie-box">
<div class="circle-image">
<i id="travel" class="fa fa-plane fly"></i>
</div>
<div class="circle-text">
<p>Travel industry</p>
</div>
</div>
<button class='toggle-effects'>[btn]</button>
#travel {
width: 50px;
height: 50px;
background-color: red;
display: block;
position: relative;
}
var $fly = $('.fly');
var flyplane = function() {
$fly.animate({
right: '-=50',
bottom: '+=50'
}, 2000, function() {
console.log('animation complete')
$fly.removeAttr("style");
flyplane();
});
};
//flyplane();
var count = 1;
$(".toggle-effects").on("click", function() {
console.log('click');
var isHidden = count++%2 !== 0;
if( isHidden ) {
$("#travel").show( 0, flyplane);
} else {
$("#travel").hide( 0 );
$fly.stop();
}
}); //end of button click

Not sure if that's what you are trying to achieve, but, if using setInterval:
You must save it into a variable, e.g variable = setInterval(function() { /* ... */ }, 2000);
To stop the interval, you must use clearInterval, e.g clearInterval(variable);.
And then, to star the interval again, you must call setInterval again, so it's better to encapsulate your code into a function, so you don't need to rewrite the same code twice.
Since, your flyplane function was already there, I only used it.
Take a look at the snippet below, and tell me if that's what you're trying to achive:
$(function() {
var $fly = $('.fly'), interval;
var flyplane = function() {
interval = setInterval(function() {
$fly.animate({
right: '-=50',
bottom: '+=50'
}, 2000, function() {
$fly.removeAttr("style");
});
}, 2000);
};
flyplane();
$(".toggle-effects").on("click", function() {
$(this).text(function(i, text) {
if (text === "Turn off effects") {
clearInterval(interval);
return "Turn on effects";
}
else {
flyplane();
return "Turn off effects";
}
})
}); //end of button click
});
.fly {
display: block;
width: 20px;
height: 20px;
background-color: yellow;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hobbie-box">
<div class="circle-image">
<i id="travel" class="fa fa-plane fly"></i>
</div>
<div class="circle-text">
<p>Travel industry</p>
</div>
</div>
<button type="button" class="btn toggle-effects">Turn off effects</button>

Thanks for your answers. I decided to try the css approach for animation using http://www.w3schools.com/css/css3_animations.asp as a guide.
All I did was add the css animation:
i.fly {
-webkit-animation-name: flying;
-webkit-animation-duration: 4s;
-webkit-animation-iteration-count: infinite;
animation-name: flying;
animation-duration: 4s;
animation-iteration-count: infinite;
}
#-webkit-keyframes flying {
0% {
right: 0px;
bottom: 0px;
}
100% {
right: -50px;
bottom: 50px;
}
}
#keyframes flying {
0% {
right: 0px;
bottom: 0px;
}
100% {
right: -50px;
bottom: 50px;
}
}
on js:
$("#travel").toggleClass("fly");
Most important thing was to toggle the effect with the button

First of all if you need an event to be executed once after a delay you should use setTimeout() function nstead of setInterval().
And instead of using .animate in JavaScript you can simply add a class fly to your element using .toggleClass() function.
This is a working snippet:
var $fly = $('.fly');
var flyplane = function() {
setTimeout(function() {
$fly.toggleClass('fly');
}, 2000);
};
flyplane();
$(".toggle-effects").on("click", function() {
$("#travel").toggle(0, flyplane);
}); //end of button click
.fly{
right: -50
bottom: +50
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hobbie-box">
<div class="circle-image">
<i id="travel" class="fa fa-plane"></i>
</div>
<div class="circle-text">
<p>Travel industry</p>
</div>
</div>
<input type="button" class="toggle-effects" value="click" />

You could just check for a var like this
$fly = $(".fly")
fly = true
flyplane = function(){
setInterval(function() {
if(fly){
$fly.animate({
right: '-=50',
bottom: '+=50'
}, 2000, function() {
$fly.removeAttr("style");
});
}
}, 2000);
};
$(".toggle-effects").on("click", function () {
fly = !fly
});
.fly{
width: 3px;
height: 3px;
position: absolute;
background-color: #00ff00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="fly"></div>

Related

Div to animate and then disappear

I am trying to make a div slide to the left and THEN disappear. I am using this code.
function slide_in(current_my) {
$("#" + current_my).animate({
left: "510"
}, {
duration: 750
});
document.getElementById(current_my).style.display = "none";
}
if I remove the last line of code the div slides nicely to the left over 750ms. But when I add the last line the div just disappears.
I tired adding:
wait(750);
before the last line, where the 'wait' function was defined as :
function wait(ms)
{
var d = new Date();
var d2 = null;
do { d2 = new Date(); }
while(d2-d < ms);
}
but that just made the div sit there for 750ms and then disappear. Again, what I want is for the 'current_my' div to slide / animate and THEN disappear (display:none). Any ideas? Thank you.
You need to use the complete option of jQuery animate. Also since you already have the object, there is no point in going to find it again. In your complete method, you can just use the this keyword and apply the hiding or any other animation directly to the object again.
$("#" + current_my).animate({ left: "510" }, { duration: 750 }, function() {
$(this).hide();
});
You should hide the div in complete callback
function slide_in(current_my) {
$("#" + current_my).animate({
left: "510"
}, 750, function() {
document.getElementById(current_my).style.display = "none";
});
}
Doc reference
Animate takes a callback when finished.
You could
function slide_in(current_my) {
$("#" + current_my).animate({
left: "510"
}, {
duration: 750
}, function () {
document.getElementById(current_my).style.display = "none";
});
}
An alternative using animate.css, you would need to adjust the animation duration on the css file.
$(document).ready(function() {
$('button.btn').click(function() {
$('div.box').addClass('animated fadeOutLeftBig');
});
});
.box {
width: 50px;
height: 50px;
margin-left: 200px;
background-color: red;
}
.box p {
text-align: center;
font-size: 1em;
}
div.box {
-webkit-animation-duration: 5s;
-webkit-animation-delay: 0s;
-moz-animation-duration: 5s;
-moz-animation-delay: 0s;
-ms-animation-duration: 5s;
-ms-animation-delay: 0s;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
<p>Test</p>
</div>
<button class="btn">Fade Left</button>
This is slightly more than asked but lets make it fun. Toss in an event to trigger the animation instead of a function, passing the location and duration numbers just for fun:
$(document).on('slidehide', '.myanimate', function(event, requstedduration, whereto, shouldhide) {
var p = $(this).position();
$(this).animate({
left: whereto
}, {
duration: requstedduration,
start: function() {$('.silly').toggle(shouldhide);},
complete: function() {
$(this).toggle(!shouldhide);
}
});
});
$('.myanimate').on('click', function() {
console.log('moving');
$(this).trigger('slidehide', [750, 510, true]);
});
// just so we can restart/see again
$(document).on('click', '.silly', function() {
console.log('restart');
$('.myanimate').show().trigger('slidehide', [750, 10, false]);;
});
.myanimate {
position: absolute;
left: 100px;
}
.silly {
display: none;
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="myanimate">howdy there (click to trigger)</div>
<div class='silly'>Animation complete. (click to restart)</div>

when click, mouseleave is triggered?

window.onload = function() {
$(".compartir").hover(function() {
console.log('hover');
var self = this;
setTimeout($(self).addClass('ready'), 500);
}, function() {
var self = this;
console.log('leave');
setTimeout($(self).removeClass('ready'), 5000);
});
$(".compartir a").on('click', function(e) {
if (!$(this).parents('.compartir').is('.ready')) {
console.log('!ready');
e.preventDefault();
} else {
console.log('ready');
}
});
};
.compartir {
position: relative;
height: 40px;
}
.compartir_box .social,
.compartir_box .showSocial {
position: absolute;
left: 0;
top: 0;
transition: 0.25s linear all;
}
.compartir_box .social {
opacity: 0;
}
.compartir_box:hover .showSocial {
opacity: 0;
}
.compartir_box:hover .social {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="compartir_box">
<div class="compartir">
<span class="showSocial">COMPARTIR</span>
<div class="social">
<a target="_blank" href="https://www.facebook.com/">facebook</a>
<a target="_blank" href="https://www.facebook.com/">twitter</a>
</div>
</div>
</div>
I want to wait untill the options are visible, because on mobile devices the hover is also a tab, and it launches the link straight away ( without the user knowing which option yet.. ) ( that's why I included the ready class )
The problem is that seems that the ready class is removed at the onclick ( without delay )
Do you know any workaround??
PD: I don't know why but the jquery is not defined in the snippet even that I included jQuery... :s
Use an anonymous function to execute in the timeout
Save the object to be used later. I prefer to save the jQuery object
clear the timeout if needed
var tId;
$(function() {
$(".compartir").hover(function() {
console.log('hover');
var $self = $(this);
clearTimeout(tId);
tId=setTimeout(function() { $self.addClass('ready')}, 500);
}, function() {
var $self = $(this);
console.log('leave');
clearTimeout(tId);
tId=setTimeout(function() { $self.removeClass('ready')}, 5000);
});
$(".compartir a").on('click', function(e) {
if (!$(this).parents('.compartir').hasClass('ready')) {
console.log('!ready');
e.preventDefault();
} else {
console.log('ready');
}
});
});
.compartir {
position: relative;
height: 40px;
}
.compartir_box .social,
.compartir_box .showSocial {
position: absolute;
left: 0;
top: 0;
transition: 0.25s linear all;
}
.compartir_box .social {
opacity: 0;
}
.compartir_box:hover .showSocial {
opacity: 0;
}
.compartir_box:hover .social {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="compartir_box">
<div class="compartir">
<span class="showSocial">COMPARTIR</span>
<div class="social">
<a target="_blank" href="https://www.facebook.com/">facebook</a>
<a target="_blank" href="https://www.facebook.com/">twitter</a>
</div>
</div>
</div>

how to detect if mouseenter or mouseleave

I am trying to achieve an effect of looping through images if a div is hovered or not.
If mouseenter div then cycle through images
if mouseleave div then stop cycling through images and remove all images (only background image will be visible).
currently I am using a setTimeout to fire itself recursively but I am having trouble with jquery on detecting if the mouse is hovering or left the object.
function logoImageLoop() {
$(".one-box .social_gallery .social_img:first").show().next(".social_img").hide().end().appendTo(".one-box .social_gallery");
};
var oneBoxIsHover = false;
$(".one-box").mouseenter(function(){
timeout();
function timeout() {
setTimeout(function(){
logoImageLoop();
timeout();
}, 100);
};
});
Here is a codepen for reference: http://codepen.io/H0BB5/pen/xEpqbv
A similar effect I am trying to achieve can be seen when hovering the cargo logo on this website: http://cargocollective.com/
You just need to clear the timer on mouseleave.
var timer = null;
$(".one-box").mouseenter(function(){
timeout();
function timeout() {
timer = setTimeout(function(){
logoImageLoop();
timeout();
}, 100);
};
}).mouseleave(function(){
clearTimeout(timer);
});
Here's a codepen: http://codepen.io/anon/pen/rrpwYJ
I would use an interval, and the JQuery .hover() functionality. Simply replacing your $(".one-box").mouseenter() with this will run the loop while you're hovered and remove it once your mouse leaves the area.
The important bit:
var imageChangeInterval;
$(".one-box").hover(function() {
imageChangeInterval = setInterval(function() {
logoImageLoop();
}, 100);
}, function() {
clearInterval(imageChangeInterval);
});
Full example:
function logoImageLoop() {
$(".one-box .social_gallery .social_img:first").show().next(".social_img").hide().end().appendTo(".one-box .social_gallery");
};
var oneBoxIsHover = false;
// New code:
var imageChangeInterval;
$(".one-box").hover(function() {
imageChangeInterval = setInterval(function() {
logoImageLoop();
}, 100);
}, function() {
clearInterval(imageChangeInterval);
});
.one-box {
position: relative;
height: 300px;
width: 300px;
}
.one-box a {
width: 100%;
}
.one-box a img {
max-width: 100%;
}
/* .social_img { display: none; } */
a#social_logo {
background-image: url(https://s3-us-west-2.amazonaws.com/staging-site-assets/one-method/instagram-logo.png);
background-repeat: no-repeat;
background-position: 0 0;
display: block;
position: absolute;
width: 73px;
height: 73px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 99;
}
.one_box .social_gallery {
position: absolute;
left: 0;
top: 0;
opacity: 1;
display: none;
}
.nav_logo .social_gallery .social_img {
position: absolute;
float: none;
margin: 0;
opacity: 1;
filter: alpha(opacity=100);
overflow: hidden;
top: 0;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="one-box nav_logo">
<a id="social_logo" href="#" alt=""></a>
<div class="social_gallery img_wall gallery">
<div class="social_img wall_img">
<a class="social_link" href="#">
<img src="https://placeholdit.imgix.net/~text?txtsize=28&bg=222&txt=300%C3%97300&w=300&h=300" />
</a>
</div>
<div class="social_img">
<a class="social_link" href="#">
<img src="https://placeholdit.imgix.net/~text?txtsize=28&bg=fb2&txt=300%C3%97300&w=300&h=300" />
</a>
</div>
<div class="social_img">
<a class="social_link" href="#">
<img src="https://placeholdit.imgix.net/~text?txtsize=28&bg=777&txt=300%C3%97300&w=300&h=300" />
</a>
</div>
<div class="social_img">
<a class="social_link" href="#">
<img src="https://placeholdit.imgix.net/~text?txtsize=28&bg=fb2&txt=300%C3%97300&w=300&h=300" />
</a>
</div>
</div>
<div>

Delaying the display:none [final] part of fadeToggle

I'm trying to find a way to delay the final part as stated in the title.
My initial JQuery code
var debounce = false;
var elements = document.getElementsByClassName('.Menu')
$('#Option1').click(function() {
if (debounce == true) {return;}
debounce = true;
$('.Menu').each(function(index) {
anim2($(this), index * 250, function() {
if (index != elements.length) {return;}
debounce = false;
})
})
});
This produces what I want to a certain extent but due to the delays and the fact that the display becomes none, I don't get what I truly want.
GIF Representing problem : https://gyazo.com/3d8f46ec3e34dfd7b88738fc00d477e1
The initial fade in works great but on the fade out when the first button disappears the delayed buttons for the other ones shift to the left which is what I'm trying not to let happen.
I tried doing:
var debounce = false;
var isClicked = false;
var elements = document.getElementsByClassName('.Menu')
$('#Option1').click(function() {
if (debounce == true) {return;}
debounce = true;
$('.Menu').each(function(index) {
anim2($(this), index * 250, function() {
if (index != elements.length) {
if (isClicked == false) {
isClicked = true;
$('.Menu').each(function(index) {
$(this).css("display", "none");
$(this).css("opacity", "0");
})
} else {
isClicked = false;
$(this).css("display", "inline-block");
$(this).css("opacity", "1");
}
}
debounce = false;
})
})
});
But it doesn't work and creates bugs. If you need to know the anim2 function it is
function anim2(object, dt, end) {
$(object).stop().delay(dt).fadeToggle({
duration: 1000,
easing: "easeOutQuad",
quene: true,
complete: end
})
}
Just going to post the relevant parts of the LESS in case it might be the cause of it
.invisible {
background: transparent;
border: none;
}
.Hamburger {
background: #pure-white;
width: 100%;
height: 5px;
opacity: 0;
position: absolute;
.rounded
}
#Option1 {
.invisible;
position: absolute;
padding: 0px 0px 0px 0px;
top: 0px;
left: 10px;
height: 100%;
width: 40px;
#TopSpan {
.Hamburger;
top: 10px;
}
#MiddleSpan {
.Hamburger;
top: 20px;
}
#BottomSpan {
.Hamburger;
top: 30px;
}
&:active {
background: #pure-red;
}
}
I have also checked out Delay of a few seconds before display:none and Hide div after a few seconds but delay() won't work since it's an automatic effect
HTML
<!DOCTYPE html>
<html lang="en">
<head class="Setup">
<link rel="stylesheet/less" type="text/css" href="../LESS/core.less"/>
<script src="../JavaScript/less.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<script type='text/javascript' src="../JavaScript/java.js"></script>
</head>
<body class="Setup">
<div class="Design">
<div class="TopDesign">
<span id="Topbar"></span>
<span id="Minibar">
<button class="Buttons" id="Option1">
<span class="Home" id="TopSpan"></span>
<span class="Home" id="MiddleSpan"></span>
<span class="Home" id="BottomSpan"></span>
</button>
<button class="Buttons Menu" id="Sub1">
<p class="SubText">Source1</p>
</button>
<button class="Buttons Menu" id="Sub2">
<p class="SubText">Source2</p>
</button>
<button class="Buttons Menu" id="Sub3">
<p class="SubText">Source3</p>
</button>
</span>
</div>
<div class="LeftDesign">
<span id="Leftbar">
<img src="" alt="">
</span>
</div>
</div>
</body>
</html>
Here is an answer not using javascript for the animation but CSS:
https://jsfiddle.net/7a1cpu0n/
I know this isn't exactly what you wanted, but it's simpler code and you should be able to apply the concept to your project. Just use CSS transition on the elements you want to show/hide and use javascript to toggle their class.
<ul>
<li>Menu</li>
<li>link1</li>
<li>link2</li>
<li>link3</li>
</ul>
$(document).ready(function(){
$('li:first-child').click(function(){
var time = 250;
$(this).siblings().each(function(){
var el = $(this);
setTimeout( function(){
el.toggleClass('show');
}, time);
time = time+250;
});
});
});
ul li:not(:first-child){
opacity: 0;
}
ul li {
float: left;
padding: 10px;
margin: 10px;
background: #e6e6e6;
list-style: none;
transition: all 1s;
}
ul li.show {
opacity: 1;
}
This is proof of concept.

How to Animate (slide) content adjacent to content with jquery toggle()

I am setting up a page which the user can hide the side bar if they wish. I am trying to use the jqeuryui to do this with the following js code
// TOGGLE JS
$(function () {
function runEffect() {
var options = {};
$("#effect").toggle('slide', options, 500);
};
$("#button").click(function () {
runEffect();
return false;
});
});
I have this working in a JSFiddle here http://jsfiddle.net/jwg4U/
However, when you look at the JSFiddle you will notice that my main content area which is a DIV called #content does not animate, it just jumps into place when I toggle the sidebar.
I would like the content div to also slide into place seamlessly and follow the toggle as it if it attached to it.
I have looked at jquery animate, but not sure how to implement this with the slide?
A Second part I am struggling with is how to change the button text when the sidebar is closed to say "Show Sidebar" - Weather it is open or closed right now it just says "Hide Sidebar"
Looking for some help
Thanks
See this updated fiddle : http://jsfiddle.net/jwg4U/23/
HTML:
<div id="container" style="width:800px">
<div id="header">
<h1>HEADER</h1>
</div>
<div class="toggler">
<div id="effect" class="ui-widget-content ui-corner-all">
<div id="menu" style="background-color:#FFD700;height:300px;width:100px;float:left;">
<h3>SIDEBAR</h3>
</div>
</div>
<div id="content" style="background-color:#EEEEEE;height:300px;">Main Content goes here</div>
</div>
Hide Sidebar
<div id="footer" style="background-color:#FFA500;clear:both;text-align:center;">
FOOTER</div>
</div>
​
JS:
// TOGGLE JS
$(function() {
var i = 0;
function runEffect() {
var options = {};
if (i === 0) {
i = 1;
$(".toggler").animate({
left: -100
}, {
duration: 500
});
}
else {
i = 0;
$(".toggler").animate({
left: 0
}, {
duration: 500
});
}
}
$("#button").click(function() {
if (i === 0) {
$(this).html("Show Sidebar");
}
else {
$(this).html("Hide Sidebar");
}
runEffect();
return false;
});
});
// TABS JS
$(function() {
$("#tabs").tabs();
});​
CSS:
.toggler {
float: left;
position: relative;
}
#button {
padding: .5em 1em;
text-decoration: none;
}
#effect {
position: relative;
float: left;
}
#content{
position: relative;
float: left;
width: 500px;
}
#button{
float: left;
clear: both;
}
#header{
background-color: #000;
color: #FFF;
}​
The jsfiddle for the complete answer : http://jsfiddle.net/jwg4U/22/
$('#effect').animate({
width: 'toggle',
height: 'toggle'
}, {
duration: 500,
specialEasing: {
width: 'linear',
height: 'linear'
},
complete: function() {
$("#content").animate(
{ left: '+=100px' },
60,
'easeInQuad',
function ()
{
if(isOpen)
{
isOpen=false;
$("#button").html('Show Sidebar');
}
else
{
isOpen=true;
$("#button").html('Hide Sidebar');
}
});
}
});

Categories

Resources