Pytanie Sortable zachowuje się nieprawidłowo po zastosowaniu skali CSS3


Skaluję element do sortowania JQuery z transformacją CSS. Oba sortowalne pozycje rozpoczynają pozycje i przesunięcia, podczas gdy przeciąganie jest nieprawidłowe. JQuery nie bierze pod uwagę skal CSS. Rozwiązałem go częściowo za pomocą kodu znalezionego tutaj:

jQuery Przeciągnij / zmień rozmiar za pomocą CSS Transform Scale

Ale rzeczą, której nie mogę rozwiązać, jest pozycja pozycji do sortowania po rozpoczęciu przeciągania. Podskakuje i trochę w prawo. Nie mogę dowiedzieć się, co dodać do obsługi zdarzenia startowego:

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

Ten Fiddle pokazuje problem: http://jsfiddle.net/adrianrosca/zbvLp/4/


11
2017-07-26 12:00


pochodzenie


Zacząłem nagrodę za to pytanie. Chociaż niekoniecznie myślę, że to pytanie jest szeroko stosowane dla dużej grupy odbiorców, ja zrobić chciałbym zobaczyć odpowiedź kanoniczną, która odnosi się do tego, co dokładnie należy dostosować w sortowalnych procedurach obsługi zdarzeń i dlaczego rozwiązanie przeciągalne jquery, które zostało zasugerowane w PO referencyjne pytanie SO, nie ma zastosowania do sortowności jquery. - Decent Dabbler


Odpowiedzi:


Jedna różnica z przeciągalny jest to, że przekształcać nie znajduje się na samych elementach, ale na rodzica. Więc zmienia nieco logikę.

Oto rozwiązanie tego konkretnego przypadku, ale zobaczysz, że w zależności od sytuacji może się zmienić. Na przykład, jeśli się zmienisz transformuj pochodzenie, lub jeśli masz poziomy do sortowania, będzie musiał zostać dostosowany. Ale logika pozostaje taka sama:

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/

EDYTOWAĆ:

Poprzednia odpowiedź będzie działać dla pozycjonowania, ale jak wskazuje Decent Dabbler, jest wada z funkcją przecięcia, która sprawdza, kiedy powinno nastąpić sortowanie. Zasadniczo pozycje są poprawnie obliczane, ale elementy pozostają szerokość i wysokość wartości, które nie są przekształcane, co powoduje problem. Możesz dostosować te wartości, modyfikując je w zdarzeniu początkowym, aby uwzględnić współczynnik skali. Na przykład:

 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/


8
2018-04-18 03:04



Zarówno Twój, jak i Odpowiedź użytkownika3765122 wydaje się rozwiązywać problem PO w równie dużym stopniu. Jednak subtelny problem, który, podejrzewam, jest sprawcą mojego własnego problemu, wydaje się pozostawać w obu: wykrywanie sortowania jest przesunięte w prawo. Jeśli chwycisz element w centrum poziomym i przeciągniesz go na inne, ostrożnie przesuwając w lewo i prawo, zobaczysz to. Ponieważ używam połączonych sortowników, które są znacznie szersze i poziome rodzeństwo, ten subtelny problem jest niezwykle powiększony. Czy wiesz, jak to zrekompensować? - Decent Dabbler
Może będę musiał zacząć nowe pytanie dla mojej konkretnej sprawy, ponieważ jest to dużo bardziej skomplikowane niż OP, ale mój problem może zniknąć, jeśli wiesz, jak rozwiązać ten subtelny problem. W każdym razie: skoro obie twoje odpowiedzi wydają się być jak dotąd równe, nie jestem do końca pewien, na jaką odpowiedź odpowiedzieć nagrodą. Mogę zdecydować o przyznaniu nagrody obu. Ale może mógłbyś wyjaśnić, dlaczego obie odpowiedzi wydają się mieć ten sam wynik? PS .: Bardzo dziękuję za dotychczasowe rozwiązania! - Decent Dabbler
Okay, bardzo dziękuję za dodanie! To robi rozwiązać problem w sprawie OP. Niestety nie rozwiązuje to mojego przypadku z moimi połączonymi urządzeniami sortującymi (połączone elementy pokazują wszystko, co ma {width: 0, height: 0, left: 0, top: 0}), ale tak jak powiedziałem, moja sprawa jest znacznie bardziej złożona. Tak więc, albo zamierzam już trochę sobie z tym pogodzić, żeby naprawdę spróbować zrozumieć zawiłości / przesunięcia / itd., Albo zacznę nowe pytanie na ten temat, jeśli nie będę w stanie tego rozgryźć. Ale nagroda jest zasłużona i dałeś mi mnóstwo wskazówek, gdzie szukać. Dzięki jeszcze raz! - Decent Dabbler


W twoim problemie są dwie rzeczy:

  1. Właściwość position elementu jest obliczana na podstawie najbliższego obiektu macierzystego, który ma pozycję absolutną lub względną. W tej chwili rodzic oparty jest na ciele, co nie jest dobre, więc musisz dodać position:relative; do pojemnika.
  2. Ponieważ, jak już zauważyłeś, JQuery nie bierze pod uwagę skal CSS przy obliczaniu obu ui.position i ui.originalPosition więc musisz "zastosować" zoomScale do obu.

CSS

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

Scenariusz

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;

To jest kod aktualizacji: http://jsfiddle.net/zbvLp/9/


1
2018-04-19 10:07



Zarówno Twój, jak i Odpowiedź Juliena Grégoire'a wydaje się rozwiązywać problem PO w równie dużym stopniu. Jednak subtelny problem, który, podejrzewam, jest sprawcą mojego własnego problemu, wydaje się pozostawać w obu: wykrywanie sortowania jest przesunięte w prawo. Jeśli chwycisz element w centrum poziomym i przeciągniesz go na inne, ostrożnie przesuwając w lewo i prawo, zobaczysz to. Ponieważ używam połączonych sortowników, które są znacznie szersze i poziome rodzeństwo, ten subtelny problem jest niezwykle powiększony. Czy wiesz, jak to zrekompensować? - Decent Dabbler
Może będę musiał zacząć nowe pytanie dla mojej konkretnej sprawy, ponieważ jest to dużo bardziej skomplikowane niż OP, ale mój problem może zniknąć, jeśli wiesz, jak rozwiązać ten subtelny problem. W każdym razie: skoro obie twoje odpowiedzi wydają się być jak dotąd równe, nie jestem do końca pewien, na jaką odpowiedź odpowiedzieć nagrodą. Mogę zdecydować o przyznaniu nagrody obu. Ale może mógłbyś wyjaśnić, dlaczego obie odpowiedzi wydają się mieć ten sam wynik? PS .: Bardzo dziękuję za dotychczasowe rozwiązania! - Decent Dabbler