2009-05-25 16 views
30

Tablo hücresinin içinde bir görüntü etiketine sahibim; başka bir tablo hücresine taşınmayı ve bu hareketin canlandırılmasını istiyorum. Kod şöyle görünürJQuery - hareketli DOM öğesini yeni ana öğeye mi hareket ettiriyorsunuz?

... Ben tercihen JQuery ile, "arrow.png" dan "CELL2" taşımak ve geçiş efekti çeşit olsun isterim

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

.

Herhangi bir fikrin var mı?

Teşekkürler!

cevap

3
iki adımda bunu yapmak gerekir

: (1) animasyon (2) rehoming.

@Ballsacian'ın işaret ettiği gibi .animate() ile ilgilenebileceğiniz animasyon. rehoming .html ile gerçekleştirilebilir() - Yukarıdaki örneğin Tabii

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

, animasyon entegre etmek bu kodu zorlaştırmak gerekir. Ve bunu yapmanın yolu, seçimin (eskiden, bir tablo satırı seçtiğini varsayarsak) eski seçim ve yeniler arasındaki satırları etkinleştirmesiyle sonuçlanmaz. Bu başarmak için daha da karmaşık olurdu.

49

Bu aslında oldukça zordur, çünkü bunu DOM'a eklemeniz ve eklemeniz gerekir; ancak konumunu korumanız gerekir. Sanırım böyle bir şey arıyorsun. Temel olarak #cell1 veya #cell2'daki okları canlandırmıyoruz. body-etiketinde yeni bir tane oluşturduk ve bunu hareketlendirdik. Bu şekilde, tablo hücresi konumları hakkında endişelenmemize gerek kalmaz, çünkü belgeye göre pozisyon alabiliriz.

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

Bu, sizi doğru yönde göstermesi gerektiğini düşünüyorum.

+0

benden bir "harika cevap" rozetiniz var :) – Sinan

+0

Haha, teşekkürler! [15 karakter] –

+0

Bana saatlerce sorun çıkarttın. Bunun için teşekkür ederim! –

48

@Pim Jager cevabı ben biraz daha temiz olduğunu düşünüyorum ile geldi

bir klon ile değiştirildi orijinal eleman beri kıracak orijinal elemana nesne referanslarını var ancak eğer, oldukça iyidir Çözüm, sadece animasyon için ortaya çıkan tek bir klona sahip olur ve sonra orijinali yeni konuma bırakır.

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

kullanmak için: moveAnimate('#ElementToMove', '#newContainer')

+1

Mükemmel işlev. Çok iyi çalışıyor! – Rocky

+0

"Uncaught TypeError:" undefined "left" özelliği "okunamıyor" hatası alıyorum, bu işlevi neden olur, neden olur? söylediğin gibi kullandım. –

+0

@ eric.itzhak Düzenlemeyi dene. – Davy8

2

biraz daha böylece artık animasyon sırasında bir araç olarak hizmet eden bir üçüncü parametre olarak bir nesne geçebilir one of the other answers genişletmiştir. Örneğin, bir <li> bir <ul>'dan diğerine taşımak isterseniz, <ul> muhtemelen <li> stilini veren belirli bir sınıfa sahiptir.

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

animasyon ise: Yani, gerçekten geçici araç kaynak veya hedef animasyon <ul> ya da aynı stil sağlar <ul> içerdeki <li> canlandırmak kullanışlı olacaktır Deniyordum

Re-ordering div positions with jQuery?

1

: şey hareketli olmaya fadein kullanır ve fadeOut hiçbir klonlama ile basit, temiz cevap verir ve hala oldukça iyi hareketi ileten bu soruyu yok @ Davy8'in işlevi oldukça iyi, ancak taşınan elemanın başlangıçtaki sayfadan çıkıp sonunda geri döndüğünde oldukça sarsıcı buldum. Diğer sayfa öğeleri aniden kayıyorsa, başka türlü düzgün bir animasyon kesintiye uğramıştır, ancak bu muhtemelen sayfa düzeninize bağlı olacaktır. Bu, @ Davy8'in işlevinin modifiye edilmiş bir versiyonudur. Bu, aynı zamanda ebeveynler arasındaki boşluğu daraltmalı ve büyütmelidir. bir eleman

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

Taşı: herkes hala bu incelemekte için

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

, ben sağlanan örnekler istediğim ve marjlar dikkate almadılar tam olarak ne uymayan bulundu, işte benim sürümü başka bir önceki: birbiri ardına $('.elementToFind').moveElement('.targetElement', 1000);

hareket bir eleman: $('.elementToFind').moveElement('.targetElement', 1000, 'after');

İlgili konular