2009-10-15 6 views
10

Je me demande s'il existe un moyen de faire glisser le jQuery uniquement vers le haut, le bas et la gauche, à droite. Je veux empêcher l'utilisateur de faire glisser une div en diagonale. L'utilisation de l'option de grille dans l'interface utilisateur déplaçable n'est pas possible dans ma situation.Comment faire glisser jQuery avec des axes X et Y fixes?

http://jqueryui.com/demos/draggable/#constrain-movement

Comment est-ce possible?

Merci!

+0

Si vous pouvez faire glisser un objet vers la gauche ou vers la droite, et de haut en bas ... ne pouvez-vous pas le faire glisser en diagonale? ou parlez-vous de la "position de départ" seulement? IE, si vous commencez à 0,0 et vous passez à un point au-delà de 0, -3 ... vous êtes soudainement contraint à la verticale seulement? – snicker

+0

Oui, c'est exactement ce que je veux réaliser. –

+0

Eh bien, j'ai écrit le code pour le faire correctement, et JQuery ne vous permettra tout simplement pas de changer l'axe pendant qu'il est traîné. – snicker

Répondre

8

J'ai écrit un plugin qui permet de déplacer un draggable dans les deux axes. Il fait le travail mais il serait mieux mis en œuvre comme un jQuery UI widget plutôt qu'un simple plugin jQuery.

hébergé Démonstration: http://jsbin.com/ugadu/1 (modifiable via http://jsbin.com/ugadu/1/edit)

code de plug-in:

$.fn.draggableXY = function(options) { 
    var defaultOptions = { 
    distance: 5, 
    dynamic: false 
    }; 
    options = $.extend(defaultOptions, options); 

    this.draggable({ 
    distance: options.distance, 
    start: function (event, ui) { 
     ui.helper.data('draggableXY.originalPosition', ui.position || {top: 0, left: 0}); 
     ui.helper.data('draggableXY.newDrag', true); 
    }, 
    drag: function (event, ui) { 
     var originalPosition = ui.helper.data('draggableXY.originalPosition'); 
     var deltaX = Math.abs(originalPosition.left - ui.position.left); 
     var deltaY = Math.abs(originalPosition.top - ui.position.top); 

     var newDrag = options.dynamic || ui.helper.data('draggableXY.newDrag'); 
     ui.helper.data('draggableXY.newDrag', false); 

     var xMax = newDrag ? Math.max(deltaX, deltaY) === deltaX : ui.helper.data('draggableXY.xMax'); 
     ui.helper.data('draggableXY.xMax', xMax); 

     var newPosition = ui.position; 
     if(xMax) { 
     newPosition.top = originalPosition.top; 
     } 
     if(!xMax){ 
     newPosition.left = originalPosition.left; 
     } 

     return newPosition; 
    } 
    }); 
}; 
+0

Cela semble intéressant mais votre lien ne fonctionne pas. Je ne peux pas savoir pourquoi ... –

+0

Argh! Désolé, il y avait une ligne de débogage qui l'a cassée à moins que Firebug ne soit ouvert. Je l'ai réparé et j'ai changé le lien dans la réponse. – brianpeiris

+2

J'ai fait une version modifiée de votre code dans le fil suivant pour prendre en charge le glisser avec l'accélération. C'est un excellent code que vous avez écrit il y a quelques années.http://stackoverflow.com/questions/6398854/jquery-draggable-with-ease – DarthJDG

1

Je n'ai pas le code exact pour vous, mais je pourrais être en mesure de vous orienter dans la bonne direction en vous aidant à réfléchir un peu plus au problème.

L'utilisateur commence alors à faire glisser un objet non contraint. Pendant que l'objet se déplace d'un pixel à une distance à partir du point de départ, si le premier pixel est à l'une de ces quatre (x, y) coordonne, où x et y sont le point de départ: (x -1, y -1), (x -1, y 1), (x 1, y -1) ou (x -1, y 1), on ne sait toujours pas dans quel sens l'utilisateur veut aller, par exemple, je Si l'objet est en bas et à gauche, il est impossible de dire si la contrainte doit être sur l'axe x ou y.

Une fois que vous avez déplacé plus d'un pixel, cela devient plus facile. Mais vous devez encore arrondir les coordonnées du pixel où, comme dans les coordonnées ci-dessus, abs (xoffset) == abs (yoffset), alors vous pouvez déclencher un événement pour appliquer la contrainte lorsque x et/ou la distance y est supérieure à un petit entier arbitraire, disons "3".

Le prochain problème à résoudre est de savoir à quelle distance du dernier tir de la contrainte d'axe voulez-vous permettre à l'utilisateur de changer l'axe. Je suppose que vous voulez un effet de grille, donc vous devrez définir un seuil déplacé en nombre de pixels avant de supprimer la contrainte et de chercher la prochaine "direction" que l'utilisateur veut faire glisser.

C'est un défi intéressant et une bonne expérience d'apprentissage si vous savez comment le faire.

3

utiliser l'événement de glisser à votre avantage

$('.selector').draggable({ 
    drag: function(event, ui) { ... } 
}); 

je ne suis pas 100% sûr de savoir comment, mais à l'intérieur ici, vous pouvez faire une vérification des coordonnées. Comme l'a dit Jack-Laplante, c'est ici que vous compareriez. si les coordonnées sont plus proches de l'axe x de l'y, changer l'axe de x

//setter 
$('.selector').draggable('option', 'axis', 'x'); 

si le contraire changer autour d'elle pour y. Cela vous donnera un mouvement d'accrochage pour toujours avoir l'élément sur l'axe des x ou l'axe des y (à partir du point de départ). vous auriez à faire un contrôle pour laisser l'élément où que ce soit si l'axe était dit (x + n, y + n), mais ce serait assez impressionnant si quelqu'un obtenait plus de quelques pixels restant sur le | x | = | y | ligne.Vous n'avez pas spécifié si les axes restaient toujours à l'origine ou s'ils changeaient en fonction de l'emplacement de l'élément déplaçable (par exemple, si vous le déplacez un peu, puis relâchez et essayez de faire glisser un peu plus). il y a un début: et fin: un événement aussi qui pourrait vous aider avec cette partie. Qu'est-ce que vous essayez exactement de faire glisser qui ne peut pas aller en diagonale, mais peut aller à gauche, à droite, en haut, et en bas?

+0

Merci pour l'entrée! Je crée une galerie d'images où l'utilisateur va faire glisser une image pour passer à l'image suivante. Si l'utilisateur fait glisser l'image vers le haut ou vers le bas, un petit texte d'information sera affiché. –

2

Je poste cette réponse après beaucoup de tripoter pour dire que ce n'est pas possible avec juste appels jqueryui sur l'objet. Il semble que cela ne vous permette pas de changer l'axe de retenue pendant que vous faites déjà glisser.

S'il vous plaît me prouver le contraire?

+0

Cela devrait être possible en utilisant un écouteur d'événement drag personnalisé et en mettant à jour l'objet ui.position. Voir [cette réponse] (http://stackoverflow.com/a/16131457/289203) pour plus de détails sur cette méthode. –

8

jQueryUI supporte deux méthodes de contrôle de glisser sur une piste fixe.

  1. Vous pouvez utiliser l'option d'axe pour limiter le mouvement en faisant glisser sur un axe particulier. Par exemple:

    $('.draggable_horiz').draggable({axis: "x"}); 
    

    Plus d'info ici: http://api.jqueryui.com/draggable/#option-axis

  2. Vous pouvez contraindre le mouvement à l'aide d'un élément ou un tableau de x/y coordonnées qui définissent un cadre de sélection.

    $('.draggable_track').draggable({ containment: [0,0, 250, 24] }); 
    
    or to just use the parent element as a reference track: 
    
        $('.draggable_track').draggable({ containment: 'parent' }); 
    

    Plus d'infos ici: http://api.jqueryui.com/draggable/#option-containment

J'espère que cette aide.

Questions connexes