2014-07-26 3 views
11

Ich skaliere ein sortierbares JQuery-Element mit CSS-Transformation. Sowohl die sortierbaren Objekte beginnen Positionen und Offsets beim Ziehen sind falsch, da JQuery keine CSS-Maßstäbe berücksichtigt. Ich löste es teilweise mit dem Code hier:Sortierbar verhält sich falsch, wenn CSS3-Skalierung angewendet wird

jQuery Drag/Resize with CSS Transform Scale

Aber das, was ich kann nicht die sortierbare Artikel Position bei Drag beginnt lösen. Es springt auf und rechts ein bisschen. Ich kann nicht herausfinden, was in den Start-Ereignishandler setzen:

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

Dieses Fiddle zeigt das Problem: http://jsfiddle.net/adrianrosca/zbvLp/4/

+0

begann ich für diese Frage eine Prämie.Obwohl ich nicht unbedingt der Meinung bin, dass diese Frage auf ein großes Publikum anwendbar ist, möchte ich eine kanonische Antwort sehen, die genau anpasst, was in den sortierbaren Ereignishandlern angepasst werden muss und warum die jquerybare Lösung vorgeschlagen wurde in OPs [referenzierte SO-Frage] (https://stackoverflow.com/q/10212683/165154), gilt nicht für jQuery-Sorables. –

Antwort

8

Ein Unterschied mit ziehbar ist, dass die Transformation ist nicht auf die Elemente selbst, aber auf dem Elternteil. Es ändert sich also ein bisschen die Logik.

Hier ist eine Lösung für diesen speziellen Fall, aber Sie werden sehen, dass sich dies je nach Situation ändern kann. Zum Beispiel, wenn Sie transform-Herkunft ändern, oder wenn Sie eine horizontale Sortierung haben, muss es angepasst werden. Aber die Logik bleibt gleich:

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/

EDIT:

vorherige Antwort wird für die Positionierung arbeiten, aber wie durch Decent Dabbler zeigt, gibt es einen Fehler mit der Schnittfunktion, die überprüft, wenn Eine Sortierung sollte erfolgen. Grundsätzlich werden Positionen korrekt berechnet, aber die Elemente behalten Breite und Höhe Werte, die nicht transformiert werden, was das Problem verursacht. Sie können diese Werte anpassen, indem Sie sie beim Start-Ereignis ändern, um den Skalierungsfaktor zu berücksichtigen. Wie dies zum Beispiel:

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

Sowohl Ihre als auch die Antwort von [user3765122] (https://stackoverflow.com/a/36715198/165154) scheinen das Problem von OP in gleichem Maße zu lösen. Ein subtiles Problem, von dem ich vermute, dass es das Problem meines Problems ist, scheint in beiden zu bestehen: Die Sorterkennung wird nach rechts verschoben. Wenn Sie ein Element in der horizontalen Mitte greifen und über andere ziehen, während Sie vorsichtig nach links und rechts wechseln, sehen Sie dies. Da ich verbundene Sortiere verwende, die viel breitere * und * horizontale Geschwister sind, ist dieses subtile Problem extrem vergrößert. Weißt du, wie das zu kompensieren ist? –

+0

Vielleicht muss ich nur eine neue Frage für meinen speziellen Fall starten, weil es viel komplexer als OP's ist, aber mein Problem kann verschwinden, wenn Sie wissen, wie man dieses subtile Problem behebt. In jedem Fall: Da Ihre Antworten bisher auf Augenhöhe zu sein scheinen, bin ich mir noch nicht ganz sicher, auf welche Antwort ich das Kopfgeld noch geben soll. Ich könnte beschließen, beiden ein Kopfgeld zu geben. Aber vielleicht könnten Sie erklären, warum beide Antworten dasselbe Ergebnis zu haben scheinen? PS .: Vielen Dank für Ihre bisherigen Lösungen! –

+0

Okay, vielen Dank für die Zugabe! Dies * löst * das Problem für den Fall von OP. Leider löst es meinen Fall mit meinen verbundenen Sortiern nicht (die verbundenen Gegenstände zeigen alle mit '{width: 0, height: 0, left: 0, top: 0}'), aber wie gesagt, mein Fall ist viel komplexer. Also werde ich entweder selbst länger damit herumspielen, um wirklich die Feinheiten von Positionierungen/Offsets/etc. Zu verstehen, oder ich werde eine neue Frage darüber starten, wenn ich nicht in der Lage bin, es herauszufinden. Aber das Kopfgeld ist gut verdient, und Sie haben mir viele Hinweise gegeben, wo Sie suchen sollten. Danke noch einmal! –

1

Es gibt zwei Dinge in Ihr Problem:

  1. Eigenschaft Position eines Elements berechnet auf der nächsten Eltern beruht, die Position absolut oder relativ hat ist. Im Moment ist der Elternteil ein Körper, der nicht gut ist, also müssen Sie position:relative; für den Container hinzufügen.
  2. Wie Sie bereits bemerken, berücksichtigt JQuery keine CSS-Skalierung, wenn Sie sowohl ui.position als auch ui.originalPosition berechnen. Sie müssen also beide auf "zoomScale" anwenden.

CSS

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

Script

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; 

Dies ist Update-Code: http://jsfiddle.net/zbvLp/9/

+0

Sowohl Ihre als auch die Antwort von [Julien Grégoire] (https://stackoverflow.com/a/36684822/165154) scheinen das Problem von OP in gleichem Maße zu lösen. Ein subtiles Problem, von dem ich vermute, dass es das Problem meines Problems ist, scheint in beiden zu bestehen: Die Sorterkennung wird nach rechts verschoben. Wenn Sie ein Element in der horizontalen Mitte greifen und über andere ziehen, während Sie vorsichtig nach links und rechts wechseln, sehen Sie dies. Da ich verbundene Sortiere verwende, die viel breitere * und * horizontale Geschwister sind, ist dieses subtile Problem extrem vergrößert. Weißt du, wie das zu kompensieren ist? –

+0

Vielleicht muss ich nur eine neue Frage für meinen speziellen Fall starten, weil es viel komplexer als OPs ist, aber mein Problem kann verschwinden, wenn Sie wissen, wie Sie dieses heikle Problem beheben können. In jedem Fall: Da Ihre Antworten bisher auf Augenhöhe zu sein scheinen, bin ich mir noch nicht ganz sicher, auf welche Antwort ich das Kopfgeld noch geben soll. Ich könnte beschließen, beiden ein Kopfgeld zu geben. Aber vielleicht könnten Sie erklären, warum beide Antworten dasselbe Ergebnis zu haben scheinen? PS .: Vielen Dank für Ihre bisherigen Lösungen! –

Verwandte Themen