Comment puis-je forcer Jquery à centrer un élément lorsqu'il est entraîné vers un autre conteneur?

Je veux des objets arrondis en forme de carré (dans ce cas, juste les cases <td> avec des nombres en eux) pour pouvoir se connecter à certaines cellules de table vides et se connecter au centre de ces cellules (cases td vides) et non à l'extérieur ) Bord de ces cellules, ce qui semble être par défaut.

Voici mon script:

 <script type="text/javascript"> $(document).ready(function () { $(".inputs div").draggable( { snap: ".spaces" }); }); </script> 

EDIT: Voici le fichier entier

  <!DOCTYPE html> <head> <title>Draggable</title> <script type="text/javascript" src="jquery-1.7.2.min.js"></script> <script type="text/javascript" src="jquery-ui-1.8.21.custom.min.js"></script> <script type="text/javascript" src="jquery.ui.touch-punch.min.js"></script> <style> .block { z-index:9999; cursor:move; } li { list-style:none; } tr { border: 2px solid black; } table { border: 2px solid black; } .inputs div { float:left; background-color:#FFFFFF; color:#004E66; font-size:x-large; margin:2px; padding:20px; border:1px solid black; } .spaces td { background-color:#666666; margin:2px; padding:36px; border:2px solid black; } </style> </head> <body> <form id="form1"> <div class="inputs"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> </div> <br/> <table class="spaces"> <tr> <td></td> <td></td> <td></td> </tr> <tr> <td></td> <td></td> <td></td> </tr> </table> </form> <!-- here we are telling jquery to make each element inside of class 'inputs' draggable --> <script type="text/javascript"> $(document).ready(function () { $(".inputs div").draggable( { snap: ".spaces" }).center(); }); </script> 

Voici une illustration basée sur le texte de ce qui se passe

 ----- + --------- +
 XXXXXXXXXXX X |
      |  |
      |  Y x |
      |  X |
 ----- + ------- + X |
      |  X |
  • Si la case ci-dessus est une cellule td dans le coin droit de la rangée tr. Supérieure
  • Alors X est l'endroit où les éléments s'accrochent actuellement (évidemment, ce n'est pas si grand, je montre juste les endroits où il colle … en fait, j'ai enlevé certains des X pour montrer comment il s'arrête au coin une fois qu'il atteint une certaine proximité À cela …)
  • Fondamentalement, ce modèle démontre que seuls les bords extérieurs de la table ont "gravité" en ce qui concerne l'élément entraînable. Ce que je veux vraiment faire, c'est de mettre en place les cellules TD avec répulsion à TOUS les arêtes, pas avec l'attrait de celles extérieures.
  • Y est l'emplacement souhaité pour l'élément traîné.
  • Enfin, pour des raisons de présentation, je voudrais que l'élément s'arrête en place avec une sorte de transition plutôt qu'un saut brutal …

Je crois que c'est ce que vous voulez.

Vous pouvez évidemment changer le positionnement si vous le souhaitez et cela correspond mieux à vos besoins.

La démo est ici: DEMO

 $(document).ready(function () { $(".inputs div").draggable( { opacity: .4, create: function(){$(this).data('position',$(this).position())}, cursorAt:{left:15}, cursor:'move', start:function(){$(this).stop(true,true)} }); $('.spaces').find('td').droppable({ drop:function(event, ui){ snapToMiddle(ui.draggable,$(this)); } }); }); function snapToMiddle(dragger, target){ var topMove = target.position().top - dragger.data('position').top + (target.outerHeight(true) - dragger.outerHeight(true)) / 2; var leftMove= target.position().left - dragger.data('position').left + (target.outerWidth(true) - dragger.outerWidth(true)) / 2; dragger.animate({top:topMove,left:leftMove},{duration:600,easing:'easeOutBack'}); } 

Une note sur la fonction snapToMiddle:

Pour pouvoir fonctionner correctement pour moi, je devais le changer à>

 function snapToMiddle(dragger, target){ var offset = target.offset(); var topMove = (target.outerHeight(true) - dragger.outerHeight(true)) / 2; var leftMove= (target.outerWidth(true) - dragger.outerWidth(true)) / 2; dragger.offset({ top: topMove + offset.top, left: leftMove + offset.left }) } 

En outre, j'ai créé un tableau qui a associé le dragger au compte-gouttes et à la réutilisation de la fenêtre. Je m'assure que tous mes compte-gouttes ne s'éloignent pas:

 $( window ).resize(function() { for( i = 0 ; i < assc.length - 1 ; i++ ) { var drp = assc[i].drop; var drg = assc[i].drag; snapToMiddle(drg,drp); } }); 

http://jsfiddle.net/vtdhV/

J'ai créé un violon qui résout votre problème … sorte de (si je comprends bien).

Les divisions rouges sont centrées dans les td s, et vous appuyez plutôt sur celles-ci. Il suffit de retirer la bordure et il apparaîtra au centre du td. La nature de .draggable amènera les .draggable à n'importe quel bord plutôt qu'à tous les arêtes simultanément.

Si cela ne suffit pas, vous devrez peut-être mettre en place un gestionnaire d'appels pour .stop qui ajuste la position de l'élément en fonction de vos attentes.

Vous devez spécifier une cible instantanée de la même taille que votre élément traîné. Ce n'est pas grave si vos draggables sont toujours de la même taille. Ajoutez simplement une division vide, absolument positionnée dans votre cellule, et configurez votre CSS afin qu'il soit dimensionné et centré correctement. Ensuite, réglez votre sélecteur snap pour être ce div. Pour n'ajouter qu'à l'intérieur de votre cible instantanée, définissez votre snapMode sur "inner" .

 $(".inputs div").draggable({ snap: ".spaces td div", snapMode: "inner" }); 

Mais si la taille de vos draggables peut varier, vous devrez redimensionner et recentrer vos cibles de suppression chaque fois que vous commencez à traîner un élément. Effectuez ceci en mousedown du draggable (Utilisez mousedown parce que dragstart est trop tard et ne fonctionne pas):

 $(".inputs div").draggable({ snap: ".spaces td div", snapMode: "inner", }).mousedown(function(){ var targets = $(".spaces td div"); targets.height(this.offsetHeight); targets.width(this.offsetWidth); targets.each(function(){ $(this).position({ of: this.parentNode }); }); }); 

http://jsfiddle.net/gilly3/mPr3A/

Ajoutez un div dans ces tds et centrez-le en donnant une largeur et une hauteur fixes pour les tds et les divs nouvellement ajoutés. Ensuite, étendez les draggables à ces divs.

 $(document).ready(function () { $('<div></div>').appendTo('.spaces td'); $(".inputs div").draggable({ snap: ".spaces td div", snapMode:'inner' }); }); 

Aussi css pour tds et divs sera comme suit.

 .block { z-index:9999; cursor:move; } .productCode { } li { list-style:none; } tr { border: 2px solid black; } table { border: 2px solid black; } .inputs div { float:left; background-color:#FFFFFF; color:#004E66; font-size:x-large; margin:2px; padding:20px; border:1px solid black; } .spaces td { background-color:#666666; width:80px; height:80px; border:2px solid black; } .spaces td div { margin:0 auto; width:50px; height:70px; } 

Fiddle Demo – http://jsfiddle.net/nsjithin/u25Bs/1/

Si j'ai bien réussi, remplacez votre script actuel par ceci:

 $(document).ready(function () { // create a bunch of invisible divs var divs = $('<div></div><div></div><div></div><div></div>'); // make them 2/2 and add them to the existing tds divs.css({ width:'50%', float:'left' }).appendTo('.spaces td'); // snap to everything $(".inputs div").draggable({snap: ".spaces td, .spaces td div" }).center(); }); 

Si je ne disais pas seulement et je vais le réparer.