2014-07-26 27 views
11

CSS dönüşümü ile JQuery sıralanabilir öğesini ölçeklendiriyorum. JQuery, CSS ölçeklerini dikkate almazsa, her iki sıralı öğe de sürükleme sırasında konumlar ve ofsetler başlar.CSS3 ölçeği uygulandığında sortable yanlış davranıyor

jQuery Drag/Resize with CSS Transform Scale

Ama çözemez şey sürükleme başlar en sıralanabilir madde konumudur: kodu bulundu ile ben kısmen çözüldü. Biraz yukarı ve yukarı atlar.

 start: function(e, ui) 
     { 
      // something is needed here to fix the initial offset 
     } 

Bu Fiddle sorunu gösterir: Ben başlangıç ​​olay işleyicisi içine koymak için anlamaya olamaz http://jsfiddle.net/adrianrosca/zbvLp/4/

+0

Ben bu soru için bir ödül başladı.Her ne kadar bu sorunun büyük bir kitleye geniş çapta uygulanabileceğini düşünmese de, * sorgulu olay işleyicilerinde tam olarak ayarlanması gerekenleri ele alan kanonik bir yanıt görmeyi seviyorum ve jQuery sürüklenebilir çözümü neden önerdi? OP’de [başvurulan SO sorusu] (https://stackoverflow.com/q/10212683/165154), jquery sıralayıcılarına uygulanamaz. –

cevap

8

farklardan biri sürüklenebilir ile üzerinde değil dönüşümü olmasıdır elemanlar kendilerini, ama ebeveyn üzerinde. Bu yüzden biraz mantığı değiştirir.

Bu özel durum için bir çözüm var, ancak duruma bağlı olarak değişebileceğini göreceksiniz. Örneğin, dönüşüm kökenini değiştirirseniz veya yatay bir sıralanabirseniz, uyarlanmış olması gerekir. Ama mantık aynı kalır:

var zoomScale = 0.5; 

$(".container") 
    .sortable({ 

    sort: function(e, ui) { 
    console.log(ui.position.left) 
     var changeLeft = ui.position.left - ui.originalPosition.left; 
     // For left position, the problem here is not only the scaling, 
     // but the transform origin. Since the position is dynamic 
     // the left coordinate you get from ui.position is not the one 
     // used by transform origin. You need to adjust so that 
     // it stays "0", this way the transform will replace it properly 
     var newLeft = ui.originalPosition.left + changeLeft/zoomScale - ui.item.parent().offset().left; 

     // For top, it's simpler. Since origin is top, 
     // no need to adjust the offset. Simply undo the correction 
     // on the position that transform is doing so that 
     // it stays with the mouse position 
     var newTop = ui.position.top/zoomScale; 

     ui.helper.css({ 
     left: newLeft, 
     top: newTop 
     }); 
    } 
    }); 

http://jsfiddle.net/aL4ntzsh/5/

DÜZENLEME:

Önceki cevap konumlandırma için çalışır, ancak iyi Dabbler tarafından işaret olarak, doğrular kesişim işlevi ile bir kusur var olacak bir sıralama yapılmalıdır. Temel olarak, pozisyonlar doğru bir şekilde hesaplanır, ancak öğeler, dönüştürülmeyen genişlik ve yükseklik değerlerini tutar ve bu da soruna neden olur. Bu değerleri, ölçek faktörünü dikkate almak için başlangıç ​​olayında değiştirerek ayarlayabilirsiniz. Örneğin bu gibi:

Sorununu iki şey vardır
start: function(e, ui) { 
     var items = $(this).data()['ui-sortable'].items; 
     items.forEach(function(item) { 
     item.height *= zoomScale; 
     item.width *= zoomScale; 
     }); 
    } 

http://jsfiddle.net/rgxnup4v/2/

+0

Hem sizin hem de [user3765122'nin cevabı] (https://stackoverflow.com/a/36715198/165154) hem OP'nin problemini hem de büyük ölçüde çözmektedir. Bununla birlikte, kendi sorunumun suçlu olduğundan şüphelendiğim süptil bir sorun, ikisinde de kalıyor gibi görünüyor: sıralama tespiti sağa kaydırılıyor. Yatay merkezde bir eleman tutup diğerlerine sürüklerseniz, dikkatli bir şekilde sola ve sağa kaydırırsanız bunu görürsünüz. Ben çok daha geniş * ve * yatay kardeşler olan bağlı sorgular kullandığım için, bu ince problem aşırı derecede büyümüştür. Bunu nasıl telafi edeceğinizi biliyor musunuz? –

+0

Belki de özel durumum için yeni bir soru başlatacağım, çünkü OP'lerden çok daha karmaşıktır, ancak bu ince sorunu nasıl çözeceğinizi biliyorsanız, sorunum kaybolabilir. Her durumda: her iki cevabınız da şimdiye kadar eşit bir temelde olduğu için, henüz ödülün hangi cevabın verileceğinden emin değilim. İkisine de bir ödül vermeyi tercih edebilirim. Ama belki de her iki cevabın da neden aynı sonucu verdiğini açıklayabilir misiniz? PS .: Çözümleriniz için şimdiye kadar çok teşekkür ederim! –

+0

Tamam, ek için çok teşekkür ederim! Bu, OP'nin vakası için sorunu çözüyor. Maalesef benim durumumla bağlantılı sıralarımda daimi çözülmüyor (bağlanan öğeler "{width: 0, height: 0, left: 0, top: 0}') şeklinde görünüyor, ama dediğim gibi benim durumum çok daha karmaşık. Yani, ya ben konumlandırma/ofsetler/vb. Inceliklerini gerçekten anlamaya çalışmak için kendimle biraz daha uğraşacağım ya da bunu anlayamazsam yeni bir soru başlatacağım. Ama ödül çok haklı ve bana nerede bakılacağına dair bir sürü ipucu verdin. Tekrar teşekkürler! –

1

: Bir elementin

  1. pozisyonu özelliği hesaplanan en yakın ebeveyn dayanmaktadır pozisyon mutlak veya göreceli olduğunu vardır. Şu anda ebeveyn temelde iyi olmayan bir vücuttır, bu yüzden kapsayıcı için position:relative; eklemeniz gerekir.
  2. Daha önce de belirttiğiniz gibi, JQuery her ikisi için de ui.position ve ui.originalPosition hesaplamaları sırasında CSS ölçeklerini dikkate almaz, dolayısıyla her ikisine de "uygulama" zoomScale "uygulamanız gerekir".

CSS

.container 
{ 
    position: relative; 
    transform: scale(0.5); 
    transform-origin: center top; 
} 

Senaryo

var changeLeft = ui.position.left - ui.originalPosition.left; 
var newLeft = (ui.originalPosition.left + changeLeft)/zoomScale; 
var changeTop = ui.position.top - ui.originalPosition.top; 
var newTop = (ui.originalPosition.top + changeTop)/zoomScale; 

Bu güncelleme kodu: http://jsfiddle.net/zbvLp/9/

+0

Hem senin, hem de [Julien Grégoire'ın cevabı] (https://stackoverflow.com/a/36684822/165154), OP'nin problemini eşit ölçüde büyük ölçüde çözüyor. Bununla birlikte, kendi sorunumun suçlu olduğundan şüphelendiğim süptil bir sorun, ikisinde de kalıyor gibi görünüyor: sıralama tespiti sağa kaydırılıyor. Yatay merkezde bir eleman tutup diğerlerine sürüklerseniz, dikkatli bir şekilde sola ve sağa kaydırırsanız bunu görürsünüz. Ben çok daha geniş * ve * yatay kardeşler olan bağlı sorgular kullandığım için, bu ince problem aşırı derecede büyümüştür. Bunu nasıl telafi edeceğinizi biliyor musunuz? –

+0

Belki de özel durumum için yeni bir soru başlatacağım, çünkü OP'lerden çok daha karmaşıktır, ancak bu ince sorunu nasıl çözeceğinizi biliyorsanız sorunum kaybolabilir. Her durumda: her iki cevabınız da şimdiye kadar eşit bir temelde olduğu için, henüz ödülün hangi cevabın verileceğinden emin değilim. İkisine de bir ödül vermeyi tercih edebilirim. Ama belki de her iki cevabın da neden aynı sonucu verdiğini açıklayabilir misiniz? PS .: Çözümleriniz için şimdiye kadar çok teşekkür ederim! –