js / jQuery Drag’n’Drop,重新计算掉落目标

我有以下问题,我有一个大树,其子节点可以根据需要折叠和展开(节点内的数据用AJAX获取)。 但是,我使用jquery.event.drop / drag来创建拖放目标。

然而,当我折叠/展开掉落目标改变位置,我需要重新计算。 这就是我想要这样做的方式:

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

折叠/展开时调用create_drop_targets()。

但是,这不起作用。 我在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 }; } 

现在我需要知道如何再次调用setup()方法,以便使用droppables的新位置重新填充$元素。

刚刚遇到同样的问题。 我在jQuery的源代码中闲逛并找到了这个(在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); ... 

所以,你只需要使用

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

似乎没有太多记录……但它解决了我的问题。 当然,让一切变慢一些,我会建议一些依赖于使用的调整(在更改发生之前启用它,并在用户移动鼠标并且发生更改后禁用它)。

也许添加jQuery 1.3中引入的直播事件会更好?

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

当我尝试在liteGrid中将滚动与可拖动行组合时,我遇到了同样的问题,但我找到了解决办法。 你的里程可能会有所不同,但我所做的是为我的拖动事件处理程序添加逻辑,检查网格是否正在滚动(这是我需要强制刷新位置的时候),如果是,我设置draggable上的refreshPositions为true。 这不会立即刷新位置,但会在下一次拖动手柄移动时刷新它们。 由于refreshPositions会降低速度,因此我会在下次拖动事件处理程序触发时重新禁用它。 最终结果是,只有当网格在liteGrid中滚动时才启用refreshPositions,并在其余时间禁用它。 这里有一些代码来说明:

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

我希望能让你免于像我一样多次撞到键盘上…

我意识到原来的问题现在已经很老了,但是我提出了一个小技巧来刷新可拖动元素的位置而没有太多开销(AFAICT)就是禁用并立即在适当的时候重新启用它们。

例如,我注意到调整浏览器窗口大小不会刷新可拖动表格行的位置,所以我这样做:

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

我希望这可以帮助那里的人!