js / jQuery拖放,重新计算放置目标

时间:2009-04-07 14:11:15

标签: javascript jquery tree

我有以下问题,我有一个大树,它有子节点,可以根据需要折叠和展开(节点内的数据用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的新位置重新填充$元素。

4 个答案:

答案 0 :(得分:3)

刚刚遇到同样的问题。我在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,
});

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

当我尝试在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
});

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

答案 3 :(得分:0)

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

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

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

我希望这有助于那里的人!