JQuery – anima l’elemento DOM in movimento verso un nuovo genitore?

Ho un tag immagine all’interno di una cella di tabella, che mi piacerebbe spostare in un’altra cella di tabella, e avere quel movimento animato.

Il codice ha un aspetto simile a questo …

Arrow  

Mi piacerebbe spostare “http://sofit.miximages.com/javascript/arrow.png” in “cell2” e avere qualche tipo di effetto di transizione, preferibilmente con JQuery.

Qualche idea?

Grazie!

Questo è in realtà abbastanza difficile perché devi rimuoverlo e aggiungerlo al DOM mantenendo la sua posizione. Penso che stai cercando qualcosa di simile. Fondamentalmente non #cell1 né la freccia in #cell1 o #cell2 . Ne creiamo solo uno nuovo nel body e lo animiamo. In questo modo non dobbiamo preoccuparci delle posizioni delle celle della tabella perché possiamo posizionarci rispetto al documento.

 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(); }); 

Penso che questo dovrebbe indirizzarti nella giusta direzione.

@Pim La risposta di Jager è piuttosto buona, tuttavia se hai riferimenti a oggetti sull’elemento originale si rompono da quando l’elemento originale è stato sostituito con un clone

Mi è venuta in mente una soluzione leggermente più pulita, in quanto ha un solo clone che si presenta per l’animazione, quindi se ne va, lasciando l’originale nella nuova posizione.

 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(); }); } 

Per utilizzare: moveAnimate('#ElementToMove', '#newContainer')

Dovrai farlo in due passaggi: (1) animazione (2) rehoming.

L’animazione di cui puoi occuparti con .animate (), come sottolinea @Ballsacian. Il rehoming può essere eseguito con .html () – per l’esempio sopra,

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

Certo, dovrai complicare quel codice per integrare l’animazione. E questo modo di farlo non causerà la selezione (presumo che tu stia selezionando una riga della tabella?) Per triggersre le righe tra la vecchia selezione e quella nuova, mentre la freccia passa da loro. Sarebbe ancora più complesso da raggiungere.

Ho esteso una delle altre risposte un po ‘oltre in modo che ora puoi passare un object come un terzo parametro che funge da veicolo durante l’animazione. Ad esempio, se vuoi spostare alcuni

  • da uno
      a un altro, il tuo
      probabilmente ha una certa class che conferisce a

    • il suo stile. Quindi, sarebbe davvero utile animare il tuo
    • all’interno di un veicolo temporaneo
        che fornisce lo stesso stile della sorgente o del target
        dell’animazione:
  •  //APPENDS AN ELEMENT IN AN ANIMATED FASHION function animateAppendTo(el, where, float){ var pos0 = el.offset(); el.appendTo(where); var pos1 = el.offset(); el.clone().appendTo(float ? float : 'body'); float.css({ 'position': 'absolute', 'left': pos0.left, 'top': pos0.top, 'zIndex': 1000 }); el.hide(); float.animate( {'top': pos1.top,'left': pos1.left}, 'slow', function(){ el.show(); float.remove(); }); } 

    Stavo provando la funzione di @ Davy8, che è abbastanza buona, ma l’ho trovata piuttosto sconcertante quando l’elemento spostato si è spezzato dalla pagina all’inizio, quindi è tornato indietro alla fine. Gli altri elementi della pagina che si spostano improvvisamente interrompono un’animazione altrimenti liscia, ma questo probabilmente dipenderà dal layout della pagina.

    Quindi questa è una versione modificata della funzione di @ Davy8, che dovrebbe anche ridurre e far crescere lo spazio tra i genitori.

     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 } 

    Se l’animazione non deve essere la cosa in movimento, questa domanda che usa fadeIn e fadeOut fornisce una risposta semplice e pulita senza clonazione e trasmette comunque abbastanza bene il movimento:

    Ri-ordinando le posizioni div con jQuery?

    Per chiunque veda ancora questo, ho trovato che gli esempi forniti non corrispondevano esattamente a quello che volevo e non hanno tenuto conto dei margini, quindi ecco la mia versione:

     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 = $('
    ').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(); }); } });

    Sposta un elemento prima di un altro: $('.elementToFind').moveElement('.targetElement', 1000);

    Sposta un elemento dopo l’altro: $('.elementToFind').moveElement('.targetElement', 1000, 'after');

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

    Esempio

      $("#go1").click(function(){ $("#block1").animate( { width:"90%" }, { queue:false, duration:3000 } ) .animate( { fontSize:"24px" }, 1500 ) .animate( { borderRightWidth:"15px" }, 1500); });