2012-07-09 66 views
4

我想要一些正方形的可拖动对象(在这种情况下只有<td>框中包含数字)可以捕捉到一些空的表格单元格并捕捉到这些单元格的中心(空的td框),而不是(外部)边缘这些细胞,这是默认情况下所做的。如何强制jquery在将元素拖动到另一个容器并将其对齐时将元素居中?

这里是我的脚本:

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

编辑:这里是整个文件

<!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> 

这里是发生了什么事情

 
-----+---------+ 
XXXXXXXXXXX X| 
    |   | 
    | Y x| 
    |  X| 
-----+-------+X| 
    |  X| 
  • 的一个粗略的基于文本的说明如果上面的框是topmos右角的td单元格t tr row
  • 然后X是元素当前粘贴的地方(显然它不是 大,我只是显示它粘贴的地方......实际上我删除了 一些X来显示它如何对齐角落一旦达到 与它的某种接近度......)
  • 基本上这个模型表明只有 表的外部边缘对于可拖动元素具有“引力”。我真正想要它 要做的就是将斥力捕捉到td单元到所有的边缘,而不是 吸引到外部的。
  • Y是拖动元素的所需抓取位置。
  • 最后呈现的原因,我想元素咬合到位 带有某种过渡,而不是突然跳跃...
+0

您是否希望可拖动的元素在tds内垂直和水平居中?因为他们不适合很好。 – 2012-07-11 05:55:13

+0

4000次阅读。 9正确的答案upvotes。 4在这个问题上。 moochers。登录你的口袋! – 2015-07-30 20:35:38

回答

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'}); 
} 
+0

哦宝贝!这是迄今为止的首要考虑。谢谢! – 2012-07-11 23:20:05

+0

好的,所以这不在我的电脑上运行。我从来没有使用过小提琴,我的代码完全按照以下方式在此页面上(https://gist.github.com/3095046)。我错过了什么? – 2012-07-12 01:29:49

+0

唯一看起来不同的是你的jQuery UI版本。 jsfiddle使用'jQuery UI 1.8.18' – Jeemusu 2012-07-12 07:59:24

-1

如果我有问题吧,有了这个替换当前的脚本:

$(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(); 

}); 

如果我不只是说,我会解决它。

+0

更好!它现在对桌子内壁有“吸引力”。但它并不坚持给定细胞的中心。 – 2012-07-11 06:10:03

+0

@David Cell你是指TD还是编号框?你还使用什么浏览器? – 2012-07-11 11:12:42

+0

在jquery或jquery ui中是否有方法'.center()'? – 2014-10-28 18:10:45

1

http://jsfiddle.net/vtdhV/

我创建了一个解决您的问题..之类的(如果我理解正确的话)小提琴。

红色divs集中在td s之内,您将捕捉到这些红色div。只要删除边框,它就会出现在td的中心。 .draggable的性质将导致可拖动对齐到任何边缘,而不是同时对齐所有边缘。

如果这还不够,您可能需要实现.stop的呼叫处理程序,根据您的期望调整元素的位置。

+0

也许我做得不对,但是当小提琴网站显示工作代码时,当我在计算机的Web服务器上尝试输出代码时,元素不可拖动。 – 2012-07-11 06:50:02

+0

@大卫你得到任何类型的错误?我从你身上复制了大部分内容。 – 2012-07-11 07:00:34

+0

没有错误只是不可拖动.. – 2012-07-11 07:04:18

0

在这些tds中添加一个div,并通过为tds和新添加的div指定固定的宽度和高度来居中它。然后跨越这些divs的可拖动。

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

另外css for tds和divs将如下所示。

.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; 
} 

小提琴演示 - http://jsfiddle.net/nsjithin/u25Bs/1/

1

你需要指定一个单元的目标,其大小为您拖动的元素相同。如果您的可拖动对象的大小始终相同,则这不是什么大问题。只需在你的单元格中添加一个空的绝对定位的div,并设置你的CSS,使其正确调整大小和居中。然后,将您的snap选择器设置为该div。要仅捕捉到捕捉目标的内部,请将您的snapMode设置为"inner"

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

但是,如果你拖拽元素的大小可能会有所不同,你需要调整和每次启动拖动一个元素时recenter您的拖放目标。做到这一点的可拖动鼠标按下的(使用mousedown因为dragstart是太晚了,不工作):

$(".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/

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 }) 
} 

此外,我创建了一个数组,关联拖动到th e滴管和窗口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); 
    } 
}); 
+0

Jon Turlington你是我的男人!任何关于如何使它动画就像jeschafe的答案的想法? 'dragger.animate({顶部:topMove,左:leftMove},{持续时间:600,缓解: 'easeOutBack'});' – Heitor 2016-05-19 07:01:57

相关问题