2009-04-07 4 views
4

J'ai le problème suivant, j'ai un grand arbre qui a des sous-noeuds qui peuvent être pliés et dépliés sur demande (les données dans les noeuds sont récupérées avec AJAX). Cependant, j'utilise jquery.event.drop/drag pour créer mes cibles glisser/déposer. Cependant, lorsque je plie/déplie les cibles de largage changent de position et j'ai besoin de recalculer. Voilà comment je voulais faire:js/jQuery Drag'n'Drop, recalculer les cibles de dépôt

function create_drop_targets() { 
    $('li a') 
    .bind('dropstart', function(event) { 
    }) 
    .bind('drop', function(event) { 
    }) 
    .bind('dropend', function(event) { 
    }); 
} 

create_drop_targets() est appelée à plier/déplier.

Cependant, cela ne fonctionne pas. Je trouve les éléments suivants dans jquery.event.drop:

var drop = $.event.special.drop = { 
    setup: function(){ 
     drop.$elements = drop.$elements.add(this); 
     drop.data[ drop.data.length ] = drop.locate(this); 
     }, 
    locate: function(elem){ // return { L:left, R:right, T:top, B:bottom, H:height, W:width } 
     var $el = $(elem), pos = $el.offset(), h = $el.outerHeight(), w = $el.outerWidth(); 
     return { elem: elem, L: pos.left, R: pos.left+w, T: pos.top, B: pos.top+h, W: w, H: h }; 
     } 

Maintenant je dois savoir comment je peux appeler la méthode setup() à nouveau il repeuple éléments $ avec les nouveaux postes pour les droppables.

Répondre

1

Peut-être vaudra-t-il mieux ajouter les événements en direct introduits dans jQuery 1.3?

$("li a").live("dropstart", function(){...});

+0

J'ai essayé ceci avec des événements en direct sur la version 1.3.2, pas de solution. – ikanobori

3

juste eu le même problème. Je déambulé dans le code source de jQuery et a trouvé cette (en ui.droppable.js):

drag: function(draggable, event) { 
    //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. 
    if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); 
    ... 

Donc, vous devez simplement avoir à utiliser

$(".cocktails").draggable({ 
    refreshPositions: true, 
}); 

ne semble pas être documenté très bien .. mais ça a réglé mon problème. Rend tout un peu plus lent bien sûr, je conseillerais quelques ajustements dépendants de l'utilisation (l'activer avant que les changements se produisent, et le désactiver une fois que l'utilisateur a déplacé sa souris et les changements ont eu lieu).

+0

Je vais essayer ça demain, je vous tiendrai au courant! – ikanobori

0

J'ai rencontré le même problème lorsque j'ai essayé de combiner le défilement avec des lignes déplaçables dans liteGrid, mais j'ai trouvé une solution de rechange. Votre kilométrage peut varier, mais j'ai ajouté une logique à mon gestionnaire d'événement de déplacement qui vérifiait si la grille était défilée (c'est à dire quand je devais forcer l'actualisation des positions de dépôt), et si oui, je sélectionnais refreshPositions à true sur le glisser-déplacer. Cela ne immédiatement actualiser les positions, mais il les fera actualiser la prochaine fois que la poignée de déplacement se déplace. Comme refreshPositions ralentit les choses, je le réinitialise la prochaine fois que mon gestionnaire d'événement drag se déclenche. Le résultat net est que refreshPositions est activé uniquement lorsque la grille défile dans liteGrid et qu'elle est désactivée le reste du temps. Voici un code pour illustrer:

//This will be called every time the user moves the draggable helper. 
function onDrag(event, ui) { 
    //We need to re-aquire the drag handle; we don't 
    //hardcode it to a selector, so this event can be 
    //used by multiple draggables. 
    var dragHandle = $(event.target); 

    //If refreshOptions *was* true, jQueryUI has already refreshed the droppables, 
    //so we can now switch this option back off. 
    if (dragHandle.draggable('option', 'refreshPositions')) { 
     dragHandle.draggable('option', 'refreshPositions', false) 
    } 

    //Your other drag handling code 

    if (/* logic to determine if your droppables need to be refreshed */) { 
       dragHandle.draggable('option', 'refreshPositions', true); 
    } 
} 


$("#mydraggable").draggable({ 
    //Your options here, note that refreshPositions is off. 
    drag: onDrag 
}); 

J'espère que vous épargnerez de éperonnage votre tête dans le clavier autant de fois que je l'ai fait ...

+0

Je devrais noter que j'ai essayé juste d'activer des refreshPositions, mais la performance était inacceptable. Avec cette solution, j'ai quand même des performances lentes quand on fait défiler les lignes, mais le reste du temps ça marche très bien (parce que refreshPositions est désactivé). –

0

Je me rends compte de la question initiale est assez vieux maintenant, mais petit truc que j'ai trouvé pour rafraîchir la position des éléments déplaçables sans beaucoup de frais généraux (AFAICT) est de les désactiver et de les réactiver immédiatement, le cas échéant.

Par exemple, je remarquais que le redimensionnement de ma fenêtre de navigateur ne pas actualiser la position de mes lignes de la table draggable, donc je l'ai fait:

$(window).resize(function() {     
    $(".draggable").draggable("option", "disabled", true); 
    $(".draggable").draggable("option", "disabled", false); 
}); 

J'espère que cela aide quelqu'un là-bas!

+0

Je vais essayer ça quelque part bientôt quand j'aurai le temps :-) – ikanobori

Questions connexes