JQuery animating more elements - javascript

I'm trying to set up an application and I need to animate several items at one time.
function getData() {
for(i=0, i<data.length, i++) {
...
animate(ID, top, left);
}
}
function animate (ID, top, left) {
$("#" + ID).animate({top: top, left: left}, {duration: 1000, queue: false});
}
What this does is, that it gets data from server through AJAX, gets ID, top and left position. I have divs with these IDs and I need to animate them to position given in left and top coordinates. Problem is, that when I call that function all elements jump to given position except the last one, which animates as it should. Where could be an issue?

You can use JQuery multiselection:
$("#element0, #element1").fadeIn()
In your case:
function getData() {
var ids = ""
for(i = 0; i < data.length; i++) {
// retrieve 'id', top and left
ids += "#" + id
if (i < data.length - 1) {
ids += ","
}
}
animate(ids, top, left);
}
function animate (ids, top, left) {
$(ids).animate({top: top, left: left}, {duration: 1000, queue: false});
}
This animate all your element, selected by 'id', simultaneously.

Related

How to remove CSS animation from element in vanilla JS

I've got a square grid of n x n smaller square div elements that I want to illuminate in a sequence with a CSS background color animation. I have a function to generate a random array for the sequence. The trouble I'm having is that once a certain square has been illuminated once, if it occurs again within the array it won't illuminate a second time. I believe it's because once the element has been assigned the CSS animation, the animation can't trigger again on that element, and I can't figure a way to make it work. It's for a Responsive Web Apps course I'm taking, and the assessment stipulates that we're only to use vanilla JS, and that all elements must be created in JS and appended to a blank <body> in our index.html.
Each flash according to the sequence is triggered through a setTimeout function that loops through all elements in the array increasing it's timer by 1s for each loop (the animation length is 1s also).
Defining containers and child divs:
function createGameContainer(n, width, height) {
var container = document.createElement('div');
//CSS styling
container.style.margin = '50px auto'
container.style.width = width;
container.style.height = height;
container.style.display = 'grid';
// loop generates string to create necessary number of grid columns based on the width of the grid of squares
var columns = '';
for (i = 0; i < n; i++) {
columns += ' calc(' + container.style.width + '/' + n.toString() + ')'
}
container.style.gridTemplateColumns = columns;
container.style.gridRow = 'auto auto';
// gap variable to reduce column and row gap for larger grid sizes
// if n is ever set to less than 2, gap is hardcoded to 20 to avoid taking square root of 0 or a negative value
var gap;
if (n > 1) {
gap = 20/Math.sqrt(n-1);
} else {
gap = 20;
}
container.style.gridColumnGap = gap.toString() + 'px';
container.style.gridRowGap = gap.toString() + 'px';
container.setAttribute('id', 'game-container');
document.body.appendChild(container);
}
/*
function to create individual squares to be appended to parent game container
*/
function createSquare(id) {
var square = document.createElement('div');
//CSS styling
square.style.backgroundColor = '#333';
//square.style.padding = '20px';
square.style.borderRadius = '5px';
square.style.display = 'flex';
square.style.alignItems = 'center';
//set class and square id
square.setAttribute('class', 'square');
square.setAttribute('id', id);
return square;
}
/*
function to create game container and and squares and append squares to parent container
parameter n denotes dimensions of game grid - n x n grid
*/
function createGameWindow(n, width, height) {
window.dimension = n;
createGameContainer(n, width, height);
/*
loop creates n**2 number of squares to fill game container and assigns an id to each square from 0 at the top left square to (n**2)-1 at the bottom right square
*/
for (i = 0; i < n**2; i++) {
var x = createSquare(i);
document.getElementById('game-container').appendChild(x);
}
}
The CSS animation:
#keyframes flash {
0% {
background: #333;
}
50% {
background: orange
}
100% {
background: #333;
}
}
.flashing {
animation: flash 1s;
}
The code to generate the array:
function generateSequence(sequenceLength) {
var sequence = [];
for (i = 0; i < sequenceLength; i++) {
var random = Math.floor(Math.random() * (dimension**2));
// the following loop ensures each element in the sequence is different than the previous element
while (sequence[i-1] == random) {
random = Math.floor(Math.random() * (dimension**2));
}
sequence[i] = random;
};
return sequence;
}
Code to apply animation to square:
function flash(index, delay) {
setTimeout( function() {
flashingSquare = document.getElementById(index);
flashingSquare.style.animation = 'flashOne 1s';
flashingSquare.addEventListener('animationend', function() {
flashingSquare.style.animation = '';
}, delay);
}
I've also tried removing and adding a class again to try and reset the animation:
function flash(index, delay) {
setTimeout( function() {
flashingSquare = document.getElementById(index);
flashingSquare.classList.remove('flashing');
flashingSquare.classList.add('flashing');
}, delay);
}
And the function to generate and display the sequence:
function displaySequence(sequenceLength) {
var sequence = generateSequence(sequenceLength);
i = 0;
while (i < sequence.length) {
index = sequence[i].toString();
flash(index, i*1000);
i++;
}
}
Despite many different attempts and a bunch of research I can't figure a way to get the animations to trigger multiple times on the same element.
Try this one:
function flash(index, delay){
setTimeout( function() {
flashingSquare = document.getElementById(index);
flashingSquare.classList.add('flashing');
flashingSquare.addEventListener('animationend', function() {
flashingSquare.classList.remove('flashing');
}, delay);
});
}
Don't remove the animation, remove the class.
Remove the class direct AFTER the animation is done. So the browser have time to handle everything to do so. And when you add the class direct BEFORE you want the animation, the browser can trigger all needed steps to do so.
Your attempt to remove and add the class was good but to fast. I think the browser and the DOM optimize your steps and do nothing.
After some research, I figured out a work around. I rewrote the function so that the setTimeout was nested within a for loop, and the setTimeout nested within an immediately invoked function expression (which I still don't fully understand, but hey, if it works). The new function looks like this:
/*
function to display game sequence
length can be any integer greater than 1
speed is time between flashes in ms and can presently be set to 1000, 750, 500 and 250.
animation length for each speed is set by a corresponding speed class
in CSS main - .flashing1000 .flashing750 .flashing500 and .flashing250
*/
function displaySequence(length, speed) {
var sequence = generateSequence(length);
console.log(sequence);
for (i = 0; i < sequence.length; i++) {
console.log(sequence[i]);
// immediately invoked function expression
(function(i) {
setTimeout( function () {
var sq = document.getElementById(sequence[i]);
sq.classList.add('flashing' + speed.toString());
sq.addEventListener('animationend', function() {
sq.classList.remove('flashing' + speed.toString());
})
}, (speed * i))
})(i);
}
}
the CSS for each class:
#keyframes flash {
0% {
background: #333;
}
50% {
background: orange
}
100% {
background: #333;
}
}
.flashing1000 {
animation: flash 975ms;
}
.flashing750 {
animation: flash 725ms;
}
.flashing500 {
animation: flash 475ms;
}
.flashing250 {
animation: flash 225ms;
}
A few lazy work arounds, I know, but it works well enough.

Scrolling upwards

I want to make a function that will automatically display items as the user scrolls upwards. Think messages, where older ones are up top, but we start at the bottom with the newest ones. I have another function that loads items at the bottom of a container, and as it does so, the current items remain in position, and scrollbar is smaller. We are not scrolled to the bottom. However, with the other direction, when I prepend items to an array, it scrolls all the way to the top, displaying the top of the loaded items, instead of remaining in the same place and letting the user scroll up as needed.
My code for the bottom scroll is this:
attachScrollWatcher: function (element, offset, callback) {
console.log('scrolling');
var contentHeight = element.scrollHeight;
var yOffset = element.scrollTop;
var y = yOffset + element.offsetHeight;
if (y >= ( contentHeight - offset ))
{
callback();
}
}
This function is attached to an object's onscroll event. However, now I need to make a function that does the opposite, going upwards. Any ideas how this can be implemented?
Basically, when scrollTop === 0 then you're at the top and you need to load a new item..
attachScrollWatcher: function (element, offset, callback) {
if(!element.scrollHeight) callback();
}
The problem is, loading a new item will keep the scrollTop at zero, so the user would have to scroll down and then scroll back up in order for the callback to be triggered again. So, what you wanna do is calculate the scrollHeight before the new item is added and then again after the item is added and then manually set the scrollTop to the difference between the original and the new scrollHeight.
Check out my example attachScrollListener method below...
class upScroller{
constructor(ele = document.body){
this.renderedItems = 0;
this.ele = ele; var i=0;
this.initBoxContents();
}
initBoxContents(){
if(this.ele.scrollHeight == this.ele.clientHeight)
this.populateNextItem().then(()=>this.initBoxContents());
else{
this.ele.scrollTop = this.ele.clientHeight;
this.attachScrollListener();
}
}
getNextItem(){
// Do something here to get the next item to render
// preferably using ajax but I'm using setTimeout
// to emulate the ajax call.
return new Promise(done=>setTimeout(()=>{
this.renderedItems++;
done(`<p>This is paragraph #${this.renderedItems}</p>`);
},50));
}
populateNextItem(){
return new Promise(done=>{
this.getNextItem().then(item=>{
this.ele.insertAdjacentHTML('afterbegin', item);
done();
});
});
}
attachScrollListener(){
this.ele.addEventListener('scroll', ()=>{
if(this.ele.scrollTop) return;
var sh = this.ele.scrollHeight;
this.populateNextItem().then(()=>{
this.ele.scrollTop = this.ele.scrollHeight - sh;
});
});
}
}
var poop = document.getElementById('poop');
new upScroller(poop);
#poop{ height: 300px; overflow: auto; border:1px solid black;}
<div id=poop></div>
I've posted this here as well....
Something like this may work.
attachScrollWatcher: function (element, offset, callback) {
console.log('scrolling');
var contentHeight = element.scrollHeight;
var yOffset = element.scrollTop;
var y = yOffset + element.offsetHeight;
if (y >= ( contentHeight - offset ))
{
callback();
} else {
callbackGoingUp();
}
}

Ordering a graphical list via mouse dragging using JavaScript

NOTE: Exact description of question follows CSS below. Sample code can be seen in this fiddle.
I have a parent div with a list of child divs within it, that looks like the following:
HTML for said container and children is:
<div class="categories_container">
<div class="category one">One</div>
<div class="category two">Two</div>
<div class="category three">Three</div>
<div class="category four">Four</div>
<div class="category five">Five</div>
<div class="category six">Six</div>
</div>
Where the classes .one, .two, .three, etc... are their relative position in the list.
The children elements are positioned with absolute positioning, within their parent.
CSS as follows (some properties not shown for simplicity):
.categories_container {
height: 324px;
width: 100%;
position: relative;
}
.category {
height: 50px;
width: 98%;
position: absolute;
left: 0px;
z-index: 0;
}
.one {
top: 0px;
}
.two {
top: 54px;
}
.three {
top: 108px;
}
.four {
top: 162px;
}
.five {
top: 216px;
}
.six {
top: 270px;
}
As can be seen in this fiddle, you can click (and hold) on any one of the child elements and move it up and down within the parent div. When you release the mouse, the selected child snaps back to its original position.
Question:
How can I detect if the selected element has been dragged overtop of another? I don't only want to know if they are overlapping, but would like to put a range on it. Something like...
if(center of current child is overtop a set range within another child){
do stuff...
}
What I'd like to do for now (as a proof of concept) is to have the underneath child's background color change WHILE the vertical center of the selected child is within the range 0.4-0.6 of the bottom child's height. If the selected child is dragged out of said region, the background should change back.
I've tried something like:
$('.category').mouseover(function(){
if(dragging){
... execute code...
}
});
But it seems that if I am dragging one element over the other, the bottom element cannot see the mouse, and so the function is never executed.
Also:
I've tried a few different methods to keep the cursor as a pointer while dragging, but no matter what it switches to the text cursor whilst dragging. So any help with that would also be appreciated.
For the pointer thing I've tried putting $(this).css('cursor', 'pointer'); in the mousedown and mouse move functions, but to no avail.
Thanks in advance! Sorry if any of this is confusing.
Here is the solution I came up with, purely with JS and JQuery, with no external libraries required and without using JQueryUI Sortables.
HTML:
<div class="list_container">
<div class="list_item">One</div>
<div class="list_item">Two</div>
<div class="list_item">Three</div>
<div class="list_item">Four</div>
<div class="list_item">Five</div>
<div class="list_item">Six</div>
</div>
where list_container holds the individual list_item elements. Is it the latter of the two which can be moved around to create your sorted list. You can put just about anything you'd like within list_item and it'll still work just fine.
CSS:
.list_container {
position: relative;
}
.list_item {
position: absolute;
z-index: 0;
left: 0px;
}
.list_item.selected {
z-index: 1000;
}
Please visit this fiddle for the full list of CSS rules (only necessary ones are shown above).
JavaScript:
I'll go through this bit-by-bit and then show the full code at the bottom.
First off, I defined an array that matches up index numbers with their written counterparts
var classes = new Array("one", "two", "three", ...);
This is used to create classes dynamically (upon page load). These classes are used to order the list. You are only required to populate this array with as many items as you will have in your list. This is the one downfall of the code I have written and am unsure of how to overcome this issue (would be VERY tedious to enter in the elements for a list of hundreds of items, or more!)
Next, a few other variables:
var margin = 2; // Space desired between each list item
var $el; // Used to hold the ID of the element that has been selected
var oldPos = 0; // The position of the selected element BEFORE animation
var newPos = 0; // The position of the selected element AFTER animation (also current position)
var dragging = false; // Whether or not an item is being moved
var numElements = $('.list_container > div').length;
// selectionHeight is the height of each list element (assuming all the same height)
// It includes the div height, the height of top and bottom borders, and the desired margin
var selectionHeight = $('.list_container .list_item').height() + parseInt($('.list_container .list_item').css("border-bottom-width")) + parseInt($('.list_container .list_item').css("border-top-width")) + margin;
var classInfo = ''; // classInfo will be populated with the information that is used to dynamically create classes upon page load
When page loads, go through each list_item and assign it a class according to its initial position in the list. Also add to classInfo the location of the TOP of the list item.
$('.list_container .list_item').each(function (index) {
$(this).addClass(classes[index]);
classInfo += '.' + classes[index] + ' {top: ' + index * selectionHeight + 'px;}\n';
});
Now, using classInfo that was created above, dynamically write the classes to the page.
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = classInfo;
document.getElementsByTagName('head')[0].appendChild(style);
The above bit of code will write the required classes into the HTML of the page. If you view the source of the page, you can see the classes in the head of the page.
Now for the ordering part. First, mousedown
$('.list_item').mousedown(function (ev) {
$el = $(this);
oldPos = $el.index() + 1;
newPos = oldPos;
dragging = true;
startY = ev.clientY; // Gets the current mouse position
startT = parseInt($el.css('top')); // Gets the current position of the TOP of the item
$el.addClass('selected'); // Adding class brings it to top (z-index) and changes color of list item
});
Next, the mousemove and mouseup functions are tied together
$(window).mousemove(function (ev) { // Use $(window) so mouse can leave parent div and still work
if (dragging) {
$el.attr('class', 'list_item') // Remove the numbered class (.one, .two, etc)
$el.addClass('selected'); // Add this class back for aesthetics
// ----- calculate new top
var newTop = startT + (ev.clientY - startY);
$el.css('cursor', 'pointer');
// ------
//------ stay in parent
var maxTop = $el.parent().height() - $el.height();
newTop = newTop < 0 ? 0 : newTop > maxTop ? maxTop : newTop;
$el.css('top', newTop);
//------
newPos = getPos(newTop, selectionHeight); // Determine what the current position of the selected list item is
// If the position of the list item has changed, move the position's current element out of the way and reassign oldPos to newPos
if (oldPos != newPos) {
moveThings(oldPos, newPos, selectionHeight);
oldPos = newPos;
}
}
}).mouseup(function () {
dragging = false; // User is no longer dragging
$el.removeClass('selected'); // Element is no longer selected
setNewClass($el, newPos); // Set the new class of the moved list item
$el.css('top', (newPos - 1) * selectionHeight); // Position the moved element where it belongs. Otherwise it'll come to rest where you release it, not in its correct position.
});
Finally, the three functions getPos, moveThings and setNewClass are as follows:
function getPos(a, b) { // a == newTop, b == selectionHeight
return Math.round( (a/b) + 1 );
}
getPos works by finding out which region the selected element is currently in. If newTop is less than .5b, then it is in region 1. If between .5b and 1.5b, then it is region 2. If between 1.5b and 2.5b, then in region 3. And so on. Write out a few cases on a piece of paper and it'll make sense what is happening.
function moveThings(a, b, c) { // a == oldPos, b == newPos, c == selectedHeight
var first = classes[b - 1]; // What is the current class of the item that will be moved
var $newEl = $('.list_container .' + first); // ID of element that will be moved
if (a < b) { // oldPos less than newPos
var second = classes[b - 2]; // The new class of the moved element will be one less
var newTop = parseInt($newEl.css('top')) - c; // Top of element will move up
} else { // oldPos more than newPos
var second = classes[b]; // The new class of the moved element will be one more
var newTop = parseInt($newEl.css('top')) + c; // Top of element will move down
}
// The following line of code is required, otherwise the following animation
// will animate of from top=0px to the new position (opposed to from top=currentPosition)
// Try taking it out and seeing
$newEl.css('top', parseInt($newEl.css('top')));
$newEl.removeClass(first); // Remove the current numbered class of element to move
// Move element and remove the added style tags (or future animations will get buggy)
$newEl.animate({top: newTop}, 300, function () {
$newEl.removeAttr('style');
});
$newEl.addClass(second); // Add the new numbered class
return false; // Cleans up animations
}
The function above is what does the actual animation part and moves the list items around to accommodate the selected list item.
function setNewClass(e, a) { // e == selected element, a == newPos
// Remove 'selected' class, then add back the 'list_item' class and the new numbered class
e.attr('class', 'list_item').addClass(classes[a-1]);
}
** All JavaScript together: **
var classes = new Array("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeem", "eighteen", "nineteen", "twenty", "twentyone", "twentytwo", "twentythree", "twentyfour");
$(document).ready(function () {
var margin = 2;
var $el;
var oldPos = 0;
var newPos = 0;
var dragging = false;
var selectionHeight = $('.list_container .list_item').height() + parseInt($('.list_container .list_item').css("border-bottom-width")) + parseInt($('.list_container .list_item').css("border-top-width")) + margin;
var classInfo = '';
$('.list_container .list_item').each(function (index) {
$(this).addClass(classes[index]);
classInfo += '.' + classes[index] + ' {top: ' + index * selectionHeight + 'px;}\n';
});
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = classInfo;
document.getElementsByTagName('head')[0].appendChild(style);
$('.list_item').mousedown(function (ev) {
$el = $(this);
oldPos = $el.index() + 1;
newPos = oldPos;
dragging = true;
startY = ev.clientY;
startT = parseInt($el.css('top'));
$el.addClass('selected');
});
$(window).mousemove(function (ev) {
if (dragging) {
$el.attr('class', 'list_item')
$el.addClass('selected');
// ----- calculate new top
var newTop = startT + (ev.clientY - startY);
$el.css('cursor', 'pointer');
// ------
//------ stay in parent
var maxTop = $el.parent().height() - $el.height();
newTop = newTop < 0 ? 0 : newTop > maxTop ? maxTop : newTop;
$el.css('top', newTop);
//------
newPos = getPos(newTop, selectionHeight);
if (oldPos != newPos) {
moveThings(oldPos, newPos, selectionHeight);
oldPos = newPos;
}
}
}).mouseup(function () {
dragging = false;
$el.removeClass('selected');
setNewClass($el, newPos);
$el.css('top', (newPos - 1) * selectionHeight);
});
});
function getPos(a, b) { // a == topPos, b == selectionHeight
return Math.round((a / b) + 1);
}
function moveThings(a, b, c) { // a == oldPos, b == newPos, c == selectedHeight
var first = classes[b - 1];
var $newEl = $('.list_container .' + first);
if (a < b) { // oldPos less than newPos
var second = classes[b - 2];
var newTop = parseInt($newEl.css('top')) - c;
} else { // oldPos more than newPos
var second = classes[b];
var newTop = parseInt($newEl.css('top')) + c;
}
$newEl.css('top', parseInt($newEl.css('top')));
$newEl.removeClass(first);
$newEl.animate({
top: newTop
}, 300, function () {
$newEl.removeAttr('style');
});
$newEl.addClass(second);
return false; // Cleans up animations
}
function setNewClass(e, a) { // e == selected element, a == newPos
e.attr('class', 'list_item').addClass(classes[a - 1]);
}

image loop in carousel jquery

I have a carousel that animates to the right depending on the li width.
After reaching the end it keeps animating until the last image is the only one you see. With a blank space to the right. How would I set it to loop so there is no blank space and the first images appears again?
My move right jquery code.
$('#right').click(function () {
if (currentItem === totalItems) {
$inner.animate({
right: '-=' + width * (totalItems-1) + 'px'
}, speed);
currentItem = 1;
} else {
$inner.animate({
right: '+=' + width
}, speed);
currentItem += 1;
}
});
So after getting to the end it rewinds to the first image.
EDIT: Here is a FIDDLE if you guys want to see.

jQuery append (or appendTo) with Animation

I have a UL-LI e.g.
<ul>
<li id="1">item-1</li>
<li id="2">item-2</li>
<li id="3">item-3</li>
<li id="4">item-4</li>
</ul>
I would like to move one of the items to another position in the list. e.g. item-2 to AFTER item-4.
Normally I can do this by deleting the item and then appending it after another.
But I would like to do this to happen visually with animation. As in, item-2 descends to after item-4.
How can I achieve this?
IDs should not start with numbers...
$('#two').slideUp(500, function () {
$('#four').after(this);
$(this).slideDown(500);
});
Here is a demo: http://jsfiddle.net/jasper/8JFBA/
Or if you always want to add the element to the end:
$('#two').slideUp(500, function () {
$('ul').append(this);
$(this).slideDown(500);
});
Here is a demo: http://jsfiddle.net/jasper/8JFBA/1/
Update
Ok, so if you want the element to slide to it's new location here ya go:
//absolutely position the element and give it a top property so it doesn't go to the top of the container
$('#two').css({ position : 'absolute', top : $('#two').position().top });
//now get the offset to the bottom of the list by getting the top offset and height for the last list-item
var lastOffset = ($(this).children().last().position().top + $(this).children().last().height());
//now animate the element to the new position
$('#two').animate({ top : lastOffset }, 1000, function () {
//when the animation is done, re-add the element to the new position in the list and reset it's position and top values
$(this).appendTo('ul').css({ position : 'relative', top : 0 });
});
And a demo: http://jsfiddle.net/jasper/8JFBA/3/
Update
You can animate not only the element being moved to the end of the list but you can animate the rest of the list items as they move up:
var $LIs = $('ul').children(),
liHeight = 20;
$LIs.on('click', function () {
var index = ($(this).index()),
$LIsAfter = $LIs.filter(':gt(' + index + ')');
console.log(index);
$(this).css({ position : 'absolute', top : $(this).position().top });
$.each($LIsAfter, function (i) {
$(this).css({ position : 'absolute', top : ((i + index + 1) * liHeight) });
});
$(this).stop(true, true).animate({ top : (($LIs.length - 1) * liHeight)}, 1000, function () {
$(this).appendTo('ul').css({ position : 'relative', top : 0 });
});
$.each($LIsAfter, function (i) {
$(this).stop(true, true).animate({ top : ((index + i) * liHeight) }, 1000, function () {
$(this).css({ position : 'relative', top : 0 });
});
});
});
Here is a demo: http://jsfiddle.net/jasper/8JFBA/8/
This isn't quite complete, there is still a bug or two, but it should help get anyone started on the idea.
I tried to implement a smoother transition when you descend and below is my version..
You need to try out the demo to understand how it works.. Select value from the drop down and hit Descend to see the animation.
DEMO
Edit: Updated top position of $from before addClass('active') to start from the exact position and not top: 0px. Thanks to Jasper for finding this issue.
var $from = $('#from');
var $to = $('#to');
$('button').click (function () {
var from = $from.val();
var to = $to.val();
var $li = $('ul li');
var $fromEl = $('#' + from);
var $toEl = $('#' + to);
//only descending
if (from == to || $li.index($fromEl) > $li.index($toEl)) return;
var destX = $toEl.position().top;
$toEl.after('<li id="tmpLi2"></li>');
$('#tmpLi2').animate({height: $fromEl.outerHeight()}, 1000);
//add a blank li for smooth animation
$fromEl
.after('<li id="tmpLi1"> </li>')
.css ('top', $fromEl.position().top)
.addClass ('active' )
.animate({
top: (destX)
},
1000,
function() {
$toEl.after(this);
$('#tmpLi2').remove();
$(this).removeClass('active');
});
$('#tmpLi1').slideUp(function() { $(this).remove()});
});

Categories

Resources