JQuery - анимация перемещения элемента DOM к новому родителю? - PullRequest
30 голосов
/ 25 мая 2009

У меня есть тег изображения внутри ячейки таблицы, который я хотел бы переместить в другую ячейку таблицы и анимировать это движение.

Код выглядит примерно так ...

<td id="cell1"><img src="arrow.png" alt="Arrow"/></td>
<td id="cell2"></td>

Я бы хотел переместить «arrow.png» в «cell2» и получить какой-то эффект перехода, желательно с JQuery.

Есть идеи?

Спасибо!

Ответы [ 8 ]

52 голосов
/ 10 июня 2009

Это на самом деле довольно сложно, потому что вы должны удалить и добавить его в DOM, но сохранить его положение. Я думаю, что вы ищете что-то вроде этого. По сути, мы не анимируем стрелку в #cell1 или #cell2. Мы просто создаем новый тег body и анимируем его. Таким образом, нам не нужно беспокоиться о позициях в ячейках таблицы, потому что мы можем располагаться относительно документа.

var $old = $('#cell1 img');
//First we copy the arrow to the new table cell and get the offset to the document
var $new = $old.clone().appendTo('#cell2');
var newOffset = $new.offset();
//Get the old position relative to document
var oldOffset = $old.offset();
//we also clone old to the document for the animation
var $temp = $old.clone().appendTo('body');
//hide new and old and move $temp to position
//also big z-index, make sure to edit this to something that works with the page
$temp
  .css('position', 'absolute')
  .css('left', oldOffset.left)
  .css('top', oldOffset.top)
  .css('zIndex', 1000);
$new.hide();
$old.hide();
//animate the $temp to the position of the new img
$temp.animate( {'top': newOffset.top, 'left':newOffset.left}, 'slow', function(){
   //callback function, we remove $old and $temp and show $new
   $new.show();
   $old.remove();
   $temp.remove();
});

Я думаю, что это должно указать вам правильное направление.

50 голосов
/ 06 марта 2011

@ Pim Jager ответ довольно хороший, однако, если у вас есть ссылки на объекты на исходный элемент, они сломаются, так как исходный элемент был заменен на клон

Я придумал, как мне кажется, более чистое решение, в котором есть только один клон, который появляется для анимации, а затем уходит, оставляя оригинал в новом месте.

function moveAnimate(element, newParent){
    //Allow passing in either a jQuery object or selector
    element = $(element);
    newParent= $(newParent);

    var oldOffset = element.offset();
    element.appendTo(newParent);
    var newOffset = element.offset();

    var temp = element.clone().appendTo('body');
    temp.css({
        'position': 'absolute',
        'left': oldOffset.left,
        'top': oldOffset.top,
        'z-index': 1000
    });
    element.hide();
    temp.animate({'top': newOffset.top, 'left': newOffset.left}, 'slow', function(){
       element.show();
       temp.remove();
    });
}

Для использования: moveAnimate('#ElementToMove', '#newContainer')

3 голосов
/ 25 мая 2009

Вам нужно будет сделать это в два этапа: (1) анимация (2) перемещение.

Анимация, о которой вы можете позаботиться с помощью .animate (), как указывает @Ballsacian. Переопределение может быть выполнено с помощью .html () - для примера выше,

var arrowMarkup = $('#cell1').html(); //grab the arrow
$('#cell1').html(""); //delete it from the first cell
$('#cell2').html(arrowMarkup); //add it to the second cell

Конечно, вам придется усложнить этот код для интеграции анимации. И этот способ не заставит выделение (я предполагаю, что вы выбираете строку таблицы?) Активировать строки между старым выделением и новым, когда стрелка проходит мимо них. Это было бы еще сложнее достичь.

2 голосов
/ 25 августа 2012

Я расширил один из других ответов немного дальше, так что теперь вы можете передать объект в качестве третьего параметра, который служит транспортным средством во время анимации. Например, если вы хотите переместить некоторые

из одного
  • . Таким образом, было бы действительно удобно анимировать
  • во временном транспортном средстве
1 голос
/ 18 марта 2016

Я пробовал функцию @ Davy8, которая довольно хороша, но я обнаружил, что это довольно неприятно, когда перемещенный элемент срывается со страницы в начале, а затем снова в конце. Другие элементы страницы, внезапно сдвигающиеся, прерывали плавную анимацию, но это, вероятно, зависело бы от макета вашей страницы.

Так что это модифицированная версия функции @ Davy8, которая также должна плавно уменьшаться и увеличивать пространство между родителями.

function moveAnimate(element, newParent,
                     slideAnimationSpeed/*=800*/, spacerAnimationSpeed/*=600*/)
{
    //Allow passing in either a jQuery object or selector
    element = $(element);
    newParent= $(newParent);
    slideAnimationSpeed=slideAnimationSpeed||800;
    spacerAnimationSpeed=spacerAnimationSpeed||600;

    var oldOffset = element.offset();
    var tempOutgoing=element.clone().insertAfter(element);
    tempOutgoing.hide(); //Don't take up space yet so 'newOffset' can be calculated correctly
    element.appendTo(newParent);
    var newOffset = element.offset();

    var tempMover = element.clone().appendTo('body');
    tempMover.css({
        'position': 'absolute',
        'left': oldOffset.left,
        'top': oldOffset.top,
        'z-index': 1000,
        'margin':0 //Necessary for animation alignment if the source element had margin
    });

    element.hide();
    element.show(spacerAnimationSpeed).css('visibility', 'hidden'); //Smoothly grow space at the target

    tempMover.animate({'top': newOffset.top, 'left': newOffset.left}, slideAnimationSpeed, function(){
       element.css('visibility', 'visible');
       tempMover.remove();
    });
    tempOutgoing.show().css('visibility', 'hidden');
    tempOutgoing.hide(spacerAnimationSpeed, function(){ tempOutgoing.remove() }); //smoothly shrink space at the source
}
0 голосов
/ 01 июля 2016

Для тех, кто все еще просматривает это, я обнаружил, что предоставленные примеры не соответствуют именно тому, что я хотел, и они не учитывают поля, поэтому вот моя версия:

jQuery.fn.extend({
    moveElement : function (newParent, speed, after) {
        var origEl   = $(this);
        var moveToEl = $(newParent);

        var oldOffset = origEl.offset();
        var temp      = origEl.clone().appendTo('body');

        temp.css({
            'position' : 'absolute',
            'left'     : parseInt(oldOffset.left) - parseInt(origEl.css('margin-left')),
            'margin'   : origEl.css('margin'),
            'top'      : oldOffset.top,
            'z-index'  : 1000,
            'height'   : moveToEl.innerHeight(),
            'width'    : moveToEl.innerWidth()
        });

        var blankEl = $('<div></div>').css({
            height   : moveToEl.innerHeight(),
            margin   : moveToEl.css('margin'),
            position : 'relative',
            width    : moveToEl.innerWidth()
        });

        if (after) {
            origEl.insertAfter(moveToEl);
            blankEl.insertAfter(newParent);
        }
        else {
            origEl.insertBefore(moveToEl);
            blankEl.insertBefore(newParent);
        }
        origEl.hide();

        var newOffset = blankEl.offset();

        temp.animate({
            'top'  : blankEl.offset().top - parseInt(moveToEl.css('margin-top')),
            'left' : newOffset.left - parseInt(moveToEl.css('margin-left'))
        }, speed, function () {
            blankEl.remove();
            origEl.show();
            temp.remove();
        });
    }
});

Переместить элемент перед другим: $('.elementToFind').moveElement('.targetElement', 1000);

Перемещение элемента за другим: $('.elementToFind').moveElement('.targetElement', 1000, 'after');

0 голосов
/ 09 октября 2015

Если анимация не должна быть движущейся вещью, этот вопрос, который использует fadeIn и fadeOut, дает простой, чистый ответ без клонирования и все же хорошо передает движение:

Переупорядочивание позиций div с помощью jQuery?

0 голосов
/ 25 мая 2009

JQuery http://docs.jquery.com/Downloading_jQuery
JQuery Effects http://docs.jquery.com/Effects/animate#paramsoptions


Пример

 $("#go1").click(function(){
      $("#block1").animate( { width:"90%" }, { queue:false, duration:3000 } )
         .animate( { fontSize:"24px" }, 1500 )
         .animate( { borderRightWidth:"15px" }, 1500);
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...