当拖动元素并将其捕捉到另一个容器时,如何强制jquery将元素居中?

bou*_*uby 4 javascript css jquery jquery-ui jquery-ui-draggable

我想要一些方形的可拖动物体(在这种情况下只是<td>带有数字的盒子)能够捕捉到一些空的表格单元并捕捉到那些单元格的中心(空的td框),而不是(外部)边缘那些细胞,这似乎是默认情况下做的.

这是我的剧本:

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

编辑:这是整个文件

 <!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>
Run Code Online (Sandbox Code Playgroud)

这是一个粗略的基于文本的插图,说明正在发生的事情

-----+---------+
XXXXXXXXXXX   X|
     |         |
     |    Y   x|
     |        X|
-----+-------+X|
     |        X|
  • 如果上面的框是最顶部tr行右角的td单元格
  • 然后X是元素当前所在的位置(显然它不是那么大,我只是展示了它所坚持的地方......实际上我删除了一些X以显示它一旦达到一定的接近程度就会卡在角落里它......)
  • 基本上这个模型表明只有表的外边缘对于可拖动元素具有"重力".我真正想要它做的是对所有边缘的排斥进入td单元,而不是对外部的吸引力.
  • Y是拖动元素的所需捕捉位置.
  • 最后由于演示原因,我希望元素在某种过渡时突然发生,而不是突然跳转......

小智 11

我相信这就是你想要的.

如果您愿意,您可以明显改变定位,更好地满足您的需求.

演示在这里: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'});
}
Run Code Online (Sandbox Code Playgroud)


小智 5

关于snapToMiddle函数的一点说明:

为了让它适合我,我不得不将其改为>

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 })
}
Run Code Online (Sandbox Code Playgroud)

此外,我创建了一个数组,将拖动器与滴管相关联,并在窗口reSize上确保我的所有滴管都不会徘徊:

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