7

Sto utilizzando l'interfaccia utente di JQuery per implementare elementi ridimensionabili/trascinabili. Ora vorrei definire un contenimento per questi elementi che limita il ridimensionamento/trascinamento su esattamente tre (!) Lati. Per esempio. dai un'occhiata a questo JSFiddle example. Puoi vedere che l'elemento contenuto può essere ridimensionato/trascinato solo all'interno dell'area del genitore.JQuery UI trascinabile: Superamento del contenimento da un lato

Quello che vorrei ottenere è che l'elemento può superare la soglia inferiore e spostarsi oltre il bordo inferiore del genitore. Tuttavia il ridimensionamento/trascinamento dovrebbe essere limitato ai lati superiore, destro e sinistro come prescritto dai confini del genitore.

Così this modification è ciò che mi si avvicinò con:

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

Se si gioca in giro con il bordo inferiore si nota che l'area del genitore viene espansa se il bambino si avvicina troppo al bordo inferiore del genitore. Sfortunatamente questo si ferma dopo 20 pixel. Dovrai quindi rilasciare il pulsante del mouse e ridimensionarlo/trascinarlo di nuovo per estendere ulteriormente l'area. Hai qualche idea del perché?

+0

Senza aver testato il codice o niente , Ho notato la seguente riga: 'if (parentElBottom <= dragElBottom + 20) {' forse che '20' sta causando il problema? –

+0

Bene, sì, è possibile spostare l'elemento nella posizione più bassa possibile che faceva parte dell'area del genitore all'inizio del movimento. Quindi l'estensione dell'area in qualche modo non viene inoltrata al modello di JQuery UI, immagino. – Bastian

risposta

5

Bene, la funzione expandParent non funzionerà perché i limiti del contenitore sono stati impostati dall'interfaccia utente di JQuery e non verranno aggiornati finché non si rilascia il mouse.

Così mi vengono in mente due soluzioni qui uno è elegante e l'altro è difficile

Ovviamente la soluzione elegante sarei qui a scrivere un proprio metodo che contiene che è libero, in fondo.

Ma ora ho una soluzione complicata utilizzando un elemento genitore fittizio e impostarne l'altezza su un valore grande come 1000 o altezza della finestra e quindi impostare l'attributo nascosto overflow per il genitore reale.

Qui è la mia soluzione:

<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

È necessario modificare il codice in base all'applicazione ho appena dato l'idea

+0

La soluzione difficile sembra essere intelligente! Quindi non c'è modo di manipolare i valori che l'interfaccia utente di JQuery sta utilizzando? Immagino che siano ambientati in qualche contenitore, quindi forse si può agire su questo. – Bastian

+1

Questa è ancora la soluzione migliore per questo particolare caso d'uso? Sto cercando di fare la stessa cosa e voglio essere sicuro che non ci siano stati miglioramenti in questo settore recentemente. – Seiyria

2

Sembra che all'interno dell'interfaccia utente di JQuery vengano mantenute le informazioni del genitore all'inizio del trascinamento, quindi anche se si cambiano le dimensioni si limiterà comunque il trascinamento.

Per risolvere il problema è possibile impostare il proprio riquadro di delimitazione.

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

Con il codice sopra, consentirà il ridimensionamento del genitore fino a 1000 + 20 di altezza. Puoi provare il codice sopra here (JSFiddle).

Se è necessario eseguire un contenitore dinamico, all'inizio (e nel metodo di ridimensionamento), impostare il nuovo contenitore con il BoundingBox corretto.

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]; 

Sì, lo so la soluzione è una specie di hacker .. ma comunque, ho appena aggiornato la JSFiddle Questa soluzione non può essere quella di calcolare e re-impostare dinamicamente la dimensione del contenitore. Volevo solo che JSFiddle funzionasse bene.

+0

Ok, questo è un approccio a cui non ho pensato, ancora. Ma è limitato ai valori assoluti, non è vero? Mi piacerebbe che il contenimento sia relativo al genitore. L'adattamento manuale della posizione del riquadro di delimitazione alla posizione del genitore sembra essere piuttosto discontinuo e prolisso. – Bastian

+0

Ho aggiunto il codice per calcolare il riquadro di delimitazione del contenimento. – wendelbsilva

+0

Ho appena aggiornato [JSFiddle] (http://jsfiddle.net/74Sxn/) con la soluzione che funziona correttamente e in modo dinamico. Volevo solo avere una versione funzionante della soluzione lì. – 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); 
       } 
      } 
     }); 
Problemi correlati