2011-10-24 18 views
5

Ho un elemento droppable dell'interfaccia utente jQuery che mi piacerebbe ottenere più grande quando un trascinabile è al passaggio del mouse su di esso. Ho provato entrambi ad usare l'opzione hoverClass e anche ad associarmi all'evento drophover.jQuery UI droppable: ridimensionamento elemento su hover non funzionante

Visivamente, entrambi questi metodi funzionano correttamente. Tuttavia, una volta che il draggable esce dal limite originale (più piccolo) del droppable, l'interfaccia utente di jQuery lo interpreta come un "dropout", nonostante sia ancora all'interno del limite corrente (più grande).

Ad esempio, js:

$("#dropable").droppable({ 
    hoverClass: 'hovering' 
}.bind('dropout', function() {console.log('dropout')}); 

css:

#droppable { background: teal; height: 10px; } 
#droppable.hovering { height: 200px; } 

In questo caso, quando un trascinabili passa sopra la droppable, i droppable aumenta visivamente per dimensioni a 200px. Se a questo punto, il draggable viene spostato verso il basso di 20px, mi aspetterei che rimanga sospeso sopra il droppable. Invece, l'interfaccia utente di jQuery attiva l'evento di dropout e l'autore di una droppable torna ad essere alto 10px.

Qualcuno sa come comportarsi come mi aspetterei?

jsFiddle esempio: http://jsfiddle.net/kWFb9/

+0

Come io non sono riuscito a trovare una risposta a questa domanda, ho passato a utilizzare il drag and Drop native API, che non ha questo problema (anche se ha una sua lista di problemi). – lucas

risposta

1

si potrebbe creare una più grande (vale a dire la dimensione del # droppable.hovering) div senza sfondo e applicare la droppable ad esso. Nota che non hai fornito HTML ma il nuovo #drop_container dovrebbe contenere entrambe le div.

JS

var dropped; 
$("#droppable").droppable({ 
    drop: function(event, ui) { 
     dropped = true; 
    } 
}); 

$('#draggable').draggable({ 
    start: function(event, ui) { 
     $("#droppable").addClass("hovering"); 
     dropped = false; 
    }, 
    stop: function(event, ui) { 
     if (!dropped) { 
      $("#droppable").removeClass("hovering"); 
     } 
    } 
}); 

CSS

#droppable { background: teal; height: 10px; } 
#droppable.hovering, #drop_container { height: 200px; } 

Oppure si potrebbe provare un'altra soluzione con .live() o .livequery() da this article

[EDIT] Ho modificato il mio codice ed ecco un jsfiddle : http://jsfiddle.net/94Qyc/1/

Ho dovuto usare una variabile globale, non ho trovato un modo migliore per controllare se la scatola è stata rilasciata. Se qualcuno ha un'idea, sarebbe fantastico.

+0

ma poi sarebbe possibile rilasciare il draggable nella parte inferiore di #drop_container senza mai interagire con #droppable, il che sarebbe fonte di confusione per l'utente. – lucas

+0

@lucas: Ho modificato la mia risposta per usare 'activate' e' deactivate'. Per favore pubblica un jsfiddle o almeno il tuo codice HTML in modo che possiamo provare se ancora non soddisfa le tue esigenze. – JMax

+0

Ho aggiunto un collegamento jsFiddle – lucas

2

così ho fatto un paio di modifiche per il vostro violino

Per prima cosa ho impostato la tolleranza droppable di "toccare" che attiverà ogni volta che una qualsiasi parte del trascinabile è toccarlo. Ciò causa l'applicazione della classe hovering.

Successivamente ho aggiunto un'animazione per ridimensionare leggermente l'elemento trascinabile. Non ero sicuro se questa fosse la funzionalità che volevi o no, quindi la inserisco comunque.

Infine, applico permanentemente la classe hovering all'elemento droppable quando l'elemento trascinabile viene rilasciato nella zona droppable.In questo modo il droppable non ritorna a quella stretta di altezza, quando c'è un elemento in esso

http://jsfiddle.net/kWFb9/2/

EDIT:

Meglio violino: http://jsfiddle.net/kWFb9/6/

Spero che questo aiuta :)

+0

Questo non ha risolto il problema. Il droppable ritorna ancora alla statura stretta quando il draggable sta passando sopra la parte inferiore di esso. Vedrete il problema se provate a trascinare il trascinabile in modo che il suo fondo sia in linea con il fondo del droppable. – lucas

+0

@ Lucas Capisco cosa intendi. Ho modificato la mia risposta con una soluzione più solida –

4

Ho avuto lo stesso problema, sono stato in grado di risolverlo utilizzando le seguenti opzioni:

$("#droppable").droppable({ 
    hoverClass: 'hovering', 
    tolerance: 'pointer' 
}); 

$('#draggable').draggable({ 
    refreshPositions: true 
}); 

Ecco il violino di lavoro: http://jsfiddle.net/kWFb9/51/

Vedi http://bugs.jqueryui.com/ticket/2970

+0

refreshPositions era esattamente ciò di cui avevo bisogno ... Sto usando il drag-n-drop di AngularJS da http://codef0rmer.github.io/angular-dragdrop e ho avuto un problema in cui onOver non sparava perché nascondevo un elemento precedente (animazione) –

+0

Buon lavoro rvignacio. Questo dovrebbe essere contrassegnato come la risposta: refreshPositions: true – jon

0

C'è un altro (hum hum) Non cattiva soluzione:

TL; DR: Fiddle

Il problema è che il plug-in memorizza i valori delle dimensioni dell'elemento dom quando il widget è stato creato (qualcosa di simile):

//jquery.ui.dropable.js 
$.widget("ui.droppable", { 
    ... 
    _create: function() { 

    var proportions, 
     this.proportions = function() { return proportions; } 

E l'offset per i widget vengono inizializzati a $ .ui.ddmanager.prepareOffsets(); Quindi dobbiamo solo sovrascrivere l'oggetto proporzioni.

This way permettono di accedere a beni di plugin in modo che possiamo scrivere qualcosa di simile:

$("#droppable").droppable({ 
    hoverClass: 'hovering', 
    over: function(ev, ui) { 
     var $widget = $(this).data('droppable'); 
     $widget.proportions = { 
      width: $(this).width(), 
      height: $(this).height() 
     };  
    }, 
    out: function(ev, ui) { 
     var $widget = $(this).data('droppable'); //ui-droppable for latests versions 
     $widget.proportions = { 
      width: $(this).width(), 
      height: $(this).height() 
     }; 
    } 
}) 
Problemi correlati