7

Używam interfejsu użytkownika JQuery do implementowania elementów skalowalnych/przeciągalnych. Teraz chciałbym zdefiniować ograniczenie dla tych elementów, które ograniczają zmianę rozmiaru/przeciągnięcia na dokładnie trzech (!) Stronach. Na przykład. spójrz na to JSFiddle example. Możesz zobaczyć, że zawarty element może być zmieniany/przeciągany tylko wewnątrz obszaru rodzica.JQuery UI przeciągalne: przekroczenie ograniczenia po jednej stronie

Co chciałbym osiągnąć, to że element może przekroczyć dolny próg i zostać przeniesiony poza dolną granicę rodzica. Niemniej jednak zmiana rozmiaru/przeciągania powinna nadal być ograniczona na górnej, prawej i lewej stronie, jak jest to określone przez rodziców zgodnie z granicami.

Więc this modification co wymyśliłem:

// resizable/draggable option 
resize/drag : function(event, ui) { 
    expandParent("#parentElement", "#dragElement"); 
} 

function expandParent(parentName, childName) { 
    var dragEl = $(childName); 
    var dragElTop = parseInt(dragEl.css("top"), 10); 
    var dragElHeight = parseInt(dragEl.css("height"), 10); 
    var dragElBottom = dragElTop + dragElHeight; 
    var parentEl = $(parentName); 
    var parentElBottom = parseInt(parentEl.css("height")); 
    if(parentElBottom <= dragElBottom + 20) { 
     parentEl.css("height", "+=2"); 
    } 
} 

Jeśli bawić się z dolnej granicy można zauważyć, że obszar rodzica jest rozszerzona, jeśli dziecko dostaje zbyt blisko dolnej granicy rodzica. Niestety zatrzymuje się po 20 pikselach. Następnie należy zwolnić przycisk myszy i ponownie zmienić rozmiar/przeciągnąć, aby rozszerzyć obszar dalej. Czy masz jakiś pomysł, dlaczego tak jest?

+0

bez przetestowane kodu lub cokolwiek , Zauważyłem następujący wiersz: 'if (parentElBottom <= dragElBottom + 20) {' może to '20' powoduje problem? –

+0

Cóż, tak, możesz przesunąć element do najniższej możliwej pozycji, która była częścią obszaru rodzica na początku ruchu. Tak więc rozszerzenie obszaru nie jest jakoś przekazane do modelu JQuery UI, jak sądzę. – Bastian

Odpowiedz

5

Cóż, funkcja expandParent nie będzie działać, ponieważ granice kontenerów zostały ustawione przez interfejs użytkownika JQuery i nie będzie aktualizowany, dopóki nie zwolnisz myszy.

więc mogę myśleć o dwóch rozwiązań jest tu jeden elegancki, a drugi jest trudne

Oczywiście eleganckim rozwiązaniem byłoby pisanie własnego zawierającą metodę, która jest za darmo na dole.

Ale teraz mam podchwytliwe rozwiązanie za pomocą dummy elementu nadrzędnego i ustawić jego wysokość na dużą wartość, jak 1000 lub wysokość okna, a następnie ustawić ukryty atrybut przepełnienia dla prawdziwego rodzica.

Oto moje rozwiązanie:

<div id="parentElement"> 
    <div id="dummy-parent"> 
     <div id="dragElement" class="dragClass"> 
      <p>Drag me around!</p> 
     </div> 
    </div> 
</div> 



function expandParent(parentName, childName) { 
    var dragEl = $(childName); 
    var parentEl = $(parentName); 
    var dragElHeight=dragEl.height(); 
    if(parentEl.height() <= dragElHeight) { 
     parentEl.height(dragElHeight); 
    } 
} 

Check the JS Fiddle

Trzeba zmodyfikować kod oparty na aplikacji i po prostu dał Ci pomysł

+0

Podejrzane rozwiązanie wydaje się być inteligentne! Więc nie ma sposobu na manipulowanie wartościami, których używa JQuery UI? Sądzę, że są ustawione w jakimś pojemniku gdzieś, więc może można na tym działać. – Bastian

+1

Czy to nadal najlepsze rozwiązanie dla tego konkretnego przypadku użycia? Zamierzam zrobić to samo i chcę się upewnić, że ostatnio nie było żadnych ulepszeń w tej dziedzinie. – Seiyria

2

Wygląda jak w interfejsie użytkownika JQuery, że przechowują informacje o rodzicu na początku przeciągania, więc nawet jeśli zmienisz rozmiar, będzie on nadal ograniczał przeciąganie.

Aby to naprawić, możesz ustawić własne okno ograniczające.

$("#dragElement") 
    .draggable({ 
     cursor  : "move", 
     scroll  : false, 
     containment : [20, 20, 400+20, 1000], 
     drag : function(event, ui) { 
      expandParent("#parentElement", "#dragElement"); 
     } 
    }) 
    .resizable({ 
     containment : "parent", 
     resize : function(event, ui) { 
      expandParent("#parentElement", "#dragElement"); 
     } 
    }); 

function expandParent(parentName, childName) { 
    var dragEl = $(childName); 
    var dragElTop = parseInt(dragEl.css("top"), 10); 
    var dragElHeight = parseInt(dragEl.css("height"), 10); 
    var dragElBottom = dragElTop + dragElHeight; 
    var parentEl = $(parentName); 
    var parentElBottom = parseInt(parentEl.css("height")); 
    if(parentElBottom <= dragElBottom + 20) { 
     parentEl.css("height", dragElBottom+20); 
    } 
} 

Z powyższego kodu, pozwoli to zmiany rozmiaru rodzica do 1000 + 20 wysokości. Możesz wypróbować powyższy kod here (JSFiddle).

Jeśli konieczne jest wykonanie dynamicznego kontenera, na początku (oraz w metodzie zmiany rozmiaru), ustaw nowy pojemnik z prawidłowym BoundingBox.

var p = $("#parentElement"); 
var dragWidth = parseInt($("#dragElement").css('width')); 
var left = p[0].offsetLeft; 
var top = p[0].offsetTop; 
var width = parseInt(p.css("width"), 10)-dragWidth; 
var containment = [left, top, width+left, 1000]; 

Tak, wiem, że rozwiązanie jest rodzaj hackish .. ale i tak, po prostu zaktualizowane JSFiddle To rozwiązanie może nie być do obliczenia i ponownie ustawić dynamicznie wielkości pojemnika. Chciałem tylko ładnie działać JSFiddle.

+0

Ok, to jest podejście, o którym jeszcze nie myślałem. Ale ogranicza się do wartości absolutnych, prawda? Chciałbym, aby ograniczenie było relatywne do rodzica. Ręczna adaptacja pozycji ramki ograniczającej do pozycji rodzica wydaje się być dość niespójna i pełna gadaniny. – Bastian

+0

Dodałem kod, aby obliczyć prostokąt ograniczający. – wendelbsilva

+0

Właśnie zaktualizowałem [JSFiddle] (http://jsfiddle.net/74Sxn/) rozwiązanie działa poprawnie i dynamicznie. Chciałem tylko mieć działającą wersję tego rozwiązania. – wendelbsilva

0
$("#dragElement") 
     .draggable({ 
      cursor  : "move", 
      containment : '#Container', 
      drag : function(event, ui) { 
       var growAmount = 10; 
       var cont = $('#Container'); 
       var item = $(ui.helper); 

       var itemOffset = item.offset(); 
       itemOffset.bottom = itemOffset.top + dProps.item.height(); 


       var contOffset= cont.offset(); 
       contOffset.bottom = contOffset.top + cont.height(); 

       if(itemOffset.bottom >= contOffset.bottom){ 
        var inst = item.draggable("instance"); 
        inst.containment = [inst.containment[0], inst.containment[1], inst.containment[2], inst.containment[3] + growAmount]; 
        cont.height(parseInt(cont.height()) + growAmount); 
       } 
      } 
     });