Passing an HTML Element into a Javascript Function - javascript

I know this has been answered, but it seems that none of the questions are relevant to exactly my point.. My code is below. I need to pass in either the variable $dynamicPanel in to the second function, or pass this in to the second function. Either way would be acceptable.
While we're at it, is there any way that I can wait some number of seconds to execute the FirstAnimation function without again using the animate() method.
$(document).ready(function FirstAnimation() {
var $dynamicPanel = $(".dynamicPanel");
$('.dynamicPanel').animate({
opacity: 0,
left: '100'
}, 5000, function () {
alert('first animation complete');
SecondAnimation(this);
});
});
function SecondAnimation(this) {
$(this).animate({
opacity: 1
}, 100, function () {
alert('second animation complete');
FirstAnimation();
});
};

this is a reserved word and can't be used as a parameter name. You should do this:
$(document).ready(function(){
FirstAnimation();
});
function FirstAnimation() {
//this function doesn't change, use your code
};
function SecondAnimation(elem) {
$(elem).animate({
opacity: 1
}, 100, function () {
alert('second animation complete');
setTimeout(function(){ //Delay FirstAnimation 7 seconds
FirstAnimation();
}, 7000);
});
};
Hope this helps. Cheers

What about changing SecondAnimation(this); to SecondAnimation($dynamicPanel);? It looks like it would do what you want.

Use SecondAnimation.apply(this).

this waiting can be done with jQuery.delay()
$(document).ready(function FirstAnimation() {
var $dynamicPanel = $(".dynamicPanel");
$dynamicPanel.animate({
opacity: 0,
left: '100'
}, 5000, function () {
alert('first animation complete');
SecondAnimation($dynamicPanel); // <--pass the proper variable ;)
});
});
function SecondAnimation(this) {
$(this).delay(5000).animate({ //<<-- wait five seconds
opacity: 1
}, 100, function () {
alert('second animation complete');
FirstAnimation();
});
};
however you can call the whole function recursive and pass the animation settings as paramaters from an array. So you reuse the function and only change the behaviour.
// store animationsettings in an array;
var animationSettings = [{opacity: 0, left: '100'},{ opacity: 1 }];
// initialize the startup index
var x = 1;
// cache selector
var $dynamicPanel = $(".dynamicPanel");
// single function
(function animate(){
x = x == 1 ? 0 : 1;//<--- toggle the index
$dynamicPanel.delay(x * 5000).animate(animationSettings[x],
1000,
function () {
animate(); // recursive call this function.
});
}());
fiddle here

Related

Add delay to JS animated text?

So I have the code below for a auto typing text animation. The text is in front of a image and I want people to see the full picture first and then the text starts to "type". I guess the best way is to add a 2-3 seconds delay before the text starts to animate but I'm not really sure how to do that.
Help would be very much appreciated. Thanks!
function cursorAnimation() {
$('#cursor').animate({
opacity: 0
}, 'fast', 'swing').animate({
opacity: 1
}, 'fast', 'swing');
}
$(document).ready(function() {
setInterval('cursorAnimation()', 1000);
});
var text = 'TEXT GOES HERE';
$.each(text.split(''), function(i, letter) {
setTimeout(function() {
$('#container').html($('#container').html() + letter);
}, 110 * i);
});
Adding some arbitrary delay is NOT the best way. You never know how much time an image will take to load on different kinds of networks, some are very fast, others might be very slow.
Instead you should fire your code on some event e.g. when the image has loaded. You can run your code on window load as an option as shown below:
function cursorAnimation() {
$('#cursor').animate({
opacity: 0
}, 'fast', 'swing').animate({
opacity: 1
}, 'fast', 'swing');
}
$(document).ready(function() {
setInterval('cursorAnimation()', 1000);
$(window).on("load", function(){
// do here tasks that you want to run after all page assets e.g. images have been loaded
showText();
});//window load()
});
function showText() {
var text = 'TEXT GOES HERE';
$.each(text.split(''), function(i, letter) {
setTimeout(function() {
$('#container').html($('#container').html() + letter);
}, 110 * i);
});
}
Try using setTimeout() function to call your function after some time i.e
$(document).ready(function() {
setTimeout(yourfunction(), 1000); //changes milliseconds as per your need.
})
https://www.w3schools.com/jsref/met_win_settimeout.asp
Generaly. It is done that you pack delayed code into callback and that callback you pass into setTimeout method. For preserving functionality while working in objects. I recomentd to call bind(this) on packaged callback.
setTimeout(function () {
console.log("Delayed message");
}.bind(this), 3000);
In your case
function cursorAnimation() {
$('#cursor').animate({
opacity: 0
}, 'fast', 'swing').animate({
opacity: 1
}, 'fast', 'swing');
}
$(document).ready(function() {
setInterval('cursorAnimation()', 1000);
});
var text = 'TEXT GOES HERE';
setTimeout(function () {
// delayed code
$.each(text.split(''), function(i, letter) {
setTimeout(function() {
$('#container').html($('#container').html() + letter);
}, 110 * i);
});
// end of delayed code
}.bind(this), 3000);

Get callback after height animation

Here I tried to run some code after height animation
<button id="btn1">Animate height</button>
<div id="box"style="background:#98bf21;height:100px;width:100px;margin:6px;"></div>
$(document).ready(function () {
$("#btn1").click(function () {
$("#box").animate({height:"300px"});
});
var x = $('#box').height();
if(x == 300){alert('animation is finished');}
});
I can't place the code which I want to run after height animation into animate method callback cause the animating box script is placed in one document and code which I want to run in other.
use jquery .promise().done
$(document).ready(function () {
$("#btn1").click(function () {
$("#box").animate({
height: "300px"
}).promise().done(function () {
alert('animation is finished');
});;
})
});
or separately like this:
$(document).ready(function () {
$("#btn1").click(function () {
$("#box").animate({
height: "300px"
});
$("#box").promise().done(function () {
alert('animation is finished');
});
})
});
Fixed Fiddle
Event-driven JavaScript a la jQuery:
//file 1
$("#box").animate({height:"300px"},function() {
$(this).trigger('myBoxFinishedAnimatingHeight');
});
//file 2
$('#box').on('myBoxFinishedAnimatingHeight',function() {
//your code
});
You can simply use the complete property as a callback function:
.animate( properties [, duration ] [, easing ] [, complete ] )
From http://api.jquery.com/animate
Here's a demo
$("#adjest").animate({"height":"300px"},1000);
$("#adjest").promise().done(
function() {
alert("done");
}
);
i would use promise and done, if you can't run it inside animate().
see here
http://jsfiddle.net/5p8Ww/
You could name space your file and call the fucntion...
var NameSpace = Namespace || {};
NameSpace.yourFunction() {
//Do stuff...
}
Then in your html/other_file
.animate( properties , 1000, ease, NameSpace.yourFunction())

Loop "animation" consisting of add/removeClasses

I'm trying to loop an "animation" of adding and removing classes:
function loading() {
$('#loading').removeClass().addClass('load0').delay(5000).removeClass().addClass('load1').delay(5000).removeClass().addClass('load2').delay(5000).removeClass().addClass('load3').delay(5000, loading);
}
loading();
Two problems:
It doesn't appear that removeClass() and addClass() can be queued with delay().
delay() doesn't appear to accept a callback function.
How can I do this?
var l = $('#loading'),
i = 0;
(function loading() {
l.removeClass().addClass('load' + i);
i = ++i % 4;
setTimeout(loading, 5000);
})();
Or we can encapsulate the variables too.
(function loading(l, i) {
l.removeClass().addClass('load' + i);
setTimeout(function() {
loading(l, ++i % 4);
}, 5000);
})($('#loading'), 0);
Modern browsers make this a little cleaner.
(function loading(l, i) {
l.removeClass().addClass('load' + i);
setTimeout(loading, 5000, l, ++i % 4);
})($('#loading'), 0);
You cannot use delay for non animating functions
Using setTimeout instead with your own callbacks might work out better.
If we're trying to loop animations why not loop animations using the .animate() with callbacks?
Example Fiddle:
http://jsfiddle.net/Culyx/fsxpZ/1/
The "arrow" in the fiddle used to be an image just a place holder div at the moment; but that should be another way of looping animations in jquery. Code for the looping animations:
$(document).ready(function () {
//looping bouncing arrow animation and speed controls
var arrowSpeed = 400;
bounceLeft = function () {
$(".arrow").animate({
left: "+=50px"
}, {
duration: arrowSpeed,
complete: bounceRight
});
}
bounceRight = function () {
$(".arrow").animate({
left: "-=50px"
}, {
duration: arrowSpeed,
complete: bounceLeft
});
}
bounceLeft();
});

How to change few css class on button in jQuery by timer?

When document is ready, there is a button that gets a new class names frame1. I want to set another class on this button after two seconds.
$(document).ready(function () {
setTimeout(function () {
$('#button').addClass('frame1')
}, 2000);
});
I want to add another class 'frame2' after two seconds if that is possible?
If you just want to add a class every coule of seconds until you have no more classes to add, you could use an interval and then clear it when the classes have all been added:
var group = [ 'whiteFG', 'redBG' ];
var intvl= setInterval(function(){
group.length
? $("#foo").addClass(group.pop())
: clearInterval(intvl) ;
}, 2000);
Fiddle: http://jsfiddle.net/EvXPy/
Or you could simply iterate over your array of class names and set timeouts from there:
$(['redBG','whiteFG']).each(function(i,o){
setTimeout(function(){
$("#foo").addClass(o);
}, i * 2000 );
});​​​​​​​​
Note that the first effect will run immediately since i is equal to the index of 0, meaning the timeout happens instantly. If you want this to be delayed, you can increment i as you see fit before multiplying by 2000.
Fiddle: http://jsfiddle.net/EvXPy/1/
You can do it this way.
$(document).ready(function () {
setTimeout(frame1(), 2000);
});
function frame1() {
$('#button').addClass('frame1');
setTimeout(frame2(), 2000);
}
function frame2() {
$('#button').addClass('frame2');
}
Or you could do it this way.
$(document).ready(function () {
setTimeout(function () {
$('#button').addClass('frame1')
}, 2000);
setTimeout(function () {
$('#button').addClass('frame2')
}, 4000);
});
setTimeout(function () {
$('#button').addClass('frame1');
}, 2000);
setTimeout(function () {
$('#button').addClass('frame2');
}, 2000);
UPDATE:
If you want to check whether class is exists then do this way.
setTimeout(function () {
$('#button').addClass('frame1');
if($('#button').hasClass('frame1')) {
setTimeout(function () {
$('#button').removeClass('frame1').addClass('frame2');
}, 2000);
}
}, 2000);
Refer LIVE DEMO

A non-nested animation sequence in jQuery?

I'm trying to create an animation sequence with jQuery where one animation starts after the previous one is done. But I just can't wrap my head around it. I've tried to make use of the jQuery.queue, but I don't think I can use that because it seems to have one individual queue for each element in the jQuery array.
I need something like:
$('li.some').each(function(){
// Add to queue
$(this).animate({ width: '+=100' }, 'fast', function(){
// Remove from queue
// Start next animation
});
});
Is there a jQuery way to do this or do I have to write and handle my own queue manually?
You can make a custom .queue() to avoid the limitless nesting..
var q = $({});
function animToQueue(theQueue, selector, animationprops) {
theQueue.queue(function(next) {
$(selector).animate(animationprops, next);
});
}
// usage
animToQueue(q, '#first', {width: '+=100'});
animToQueue(q, '#second', {height: '+=100'});
animToQueue(q, '#second', {width: '-=50'});
animToQueue(q, '#first', {height: '-=50'});
Demo at http://jsfiddle.net/gaby/qDbRm/2/
If, on the other hand, you want to perform the same animation for a multitude of elements one after the other then you can use their index to .delay() each element's animation for the duration of all the previous ones..
$('li.some').each(function(idx){
var duration = 500;
$(this).delay(duration*idx).animate({ width: '+=100' }, duration);
});
Demo at http://jsfiddle.net/gaby/qDbRm/3/
The callback of .animate() actually accepts another .animate(), so all you would have to do would be
$(this).animate({ width: '+=100' }, 'fast', function(){
$(selector).animate({attr: val}, 'speed', function(){
});
});
and so on.
You could call the next one recursively.
function animate(item) {
var elem = $('li.some').eq(item);
if(elem.length) {
elem.animate({ width: '+=100' }, 'fast', function() {
animate(item + 1);
});
}
}
animate(0);
why not build up a queue?
var interval = 0; //time for each animation
var speed = 200;
$('li.some').each(function(){
interval++;
$(this).delay(interval * speed).animate({ width: '+=100' }, speed);
});
EDIT: added speed param
Thanks to everybody replying!
I thought I should share the outcome of my question. Here is a simple jQuery slideDownAll plugin that slides down one item at a time rather than all at once.
(function ($) {
'use strict';
$.fn.slideDownAll = function (duration, callback) {
var that = this, size = this.length, animationQueue = $({});
var addToAnimationQueue = function (element, duration, easing, callback) {
animationQueue.queue(function (next) {
$(element).slideDown(duration, easing, function () {
if (typeof callback === 'function') {
callback.call(this);
}
next();
});
});
};
return this.each(function (index) {
var complete = null,
easing = 'linear';
if (index + 1 === size) {
complete = callback;
easing = 'swing';
}
addToAnimationQueue(this, duration / size, easing, complete);
});
};
} (jQuery));
Not very well test, but anyways.
Enjoy!!

Categories