• 0

[jQuery] Swap Element Positions


Question

18 answers to this question

Recommended Posts

  • 0

Something along the lines of

	(function( $ ){
		$.fn.swap = function(other,speed) {
			//get the position
			var position1 = this.offset();
			var position2 = other.offset();

			//position this where it is
			this.css({
				top: position1.top + 'px',
				left: position1.left + 'px',
				position: 'absolute'
			});

			//position the other element where it is
			other.css({
				top: position2.top + 'px',
				left: position2.left + 'px',
				position: 'absolute'
			});

			this.animate({
				'top': position2.top + 'px',
				'left': position2.left + 'px'
			}, speed, function() {
					// Animation complete.
			});

			other.animate({
				'top': position1.top + 'px',
				'left': position1.left + 'px'
			}, speed, function() {
				// Animation complete.
			});
		};
	})( jQuery );

	//add animate when we clicky trigger
	$('#trigger').click(function(e) {
					$('#element1').swap($('#element2'),300);
				});

  • 0

$(document).ready(function()
{
	$('#startAnimation').click(function()
	{
		$('#item1').animate({
			top: $('.item:eq(1)').css('top'),
			left: $('.item:eq(1)').css('left')
		}, 500);

		$('#item2').animate({
			top: $('.item:eq(0)').css('top'),
			left: $('.item:eq(0)').css('left')
		}, 500);
	});
});

Was bored in work and remember seeing this topic before I left this morning... said i'd give it a go. Beaten to the punch it seems :p

  • 0
  On 12/08/2011 at 10:10, Quigley Guy said:

$(document).ready(function()
{
	$('#startAnimation').click(function()
	{
		$('#item1').animate({
			top: $('.item:eq(1)').css('top'),
			left: $('.item:eq(1)').css('left')
		}, 500);

		$('#item2').animate({
			top: $('.item:eq(0)').css('top'),
			left: $('.item:eq(0)').css('left')
		}, 500);
	});
});

Was bored in work and remember seeing this topic before I left this morning... said i'd give it a go. Beaten to the punch it seems :p

I also saw this at work and though it would be a good excuse to finally check out jQuery. Made me wanna marry jQuery though, and divorce Dojo

  • 0

So hears my code so far: http://jsfiddle.net/LYc3E/3/

I've not been able to include all your cool visual animations because I've been having problems with the absolute positioning.

Can someone try to put that in for me?

Remember, Paragraph 1 and Paragraph 2 shoudl not jump or jitter, if you don't know the height or the top location of the DIVs.

  • 0

$(document).ready(function()
{
    var animationSteps = 0;
    var animationInProgress = false;

    $('#item-queue').css('height', $('#item-queue').height());

    $('#item-queue .item').each(function()
    {
        var top = 0;

        $(this).prevAll().each(function() {
            top += $(this).outerHeight();
        });

        $(this).css('top', top + 'px');
        $(this).css('position', 'absolute');
    });

    $('#item-queue .item .arrow').click(function()
    {
        if(animationInProgress == false)
        {
            var item = $(this).parent();
            var direction = ($(this).hasClass('up') ? 'up' : 'down');

            if(direction == 'up' && $(item).attr('data-order') > 1)
            {
                var swap = $('.item[data-order="' + (parseInt($(item).attr('data-order'), 10) - 1) + '"]');
                moveItem(item, swap, direction);
            }
            else if(direction == 'down' && $(item).attr('data-order') != $('#item-queue').children().length)
            {
                var swap = $('.item[data-order="' + (parseInt($(item).attr('data-order'), 10) + 1) + '"]');
                moveItem(item, swap, direction);
            }
        }
    });

    function moveItem(item, swap, direction)
    {
        animationInProgress = true;

        var itemTop = 0;
        var swapTop = 0;

        if(direction == 'up')
        {
            itemTop = parseInt($(item).css('top'), 10) - $(swap).outerHeight();
            swapTop = parseInt($(swap).css('top'), 10) + $(item).outerHeight();
        }
        else if(direction == 'down')
        {
            itemTop = parseInt($(item).css('top'), 10) + $(swap).outerHeight();
            swapTop = parseInt($(swap).css('top'), 10) - $(item).outerHeight();
        }

        $(item).animate({
            top: itemTop + 'px'
        }, 500, function()
        {
            animationSteps++;
            if(animationSteps == 2) resetAnimationValues();
        });

        $(swap).animate({
            top: swapTop + 'px'
        }, 500, function()
        {
            animationSteps++;
            if(animationSteps == 2) resetAnimationValues();
        });

        var swapValue = $(item).attr('data-order');

        $(item).attr('data-order', $(swap).attr('data-order'));
        $(swap).attr('data-order', swapValue);
    }

    function resetAnimationValues()
    {
        animationSteps = 0;
        animationInProgress = false;
    }
});

now...

All items are displayed normally on the page. Once the page has loaded each of the items in the queue are positioned absolutely (in relation to the relative queue element).

I am now using a custom attribute to record the order of the elements are on-screen as DOM order does not matter in absolutely positioned items.

Have a look at the latest code in action...

  • 0
  On 14/08/2011 at 20:55, Brian Miller said:

What does this line do?

$('#item-queue').css('height', $('#item-queue').height());

Sets the height of the item-queue element so that the content below it does not shift.

  • 0
  On 14/08/2011 at 21:06, Mathachew said:

Sets the height of the item-queue element so that the content below it does not shift.

Exactly, the height is initially set to 'auto' so once all the containing children are set to absolute (removed from the normal flow of the document) the actual height of the container will be reduced to 0.

Try it out yourself by removing that one line of javascript and putting extra content underneath the item-queue div.

  • 0
  On 14/08/2011 at 21:33, Brian Miller said:

Good stuff.

I was confused, thinking it was the equivalent to x=x, which seemed unneeded but your explanation makes sense.

The first part sets the height, while the second gets the height. Breaking it down looks like this:

var height = $('#item-queue').height();

$('#item-queue').css('height', height);

// alternate set method
$('#item-queue').height(height);

The result is the same in either case. There are several jQuery functions that operate as a getter/setter: height, width, html, text, and val immediately come to mind.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.