在 jQuery UI 中克隆可拖动对象时,如何将数据和事件传输到新元素?

Posted

技术标签:

【中文标题】在 jQuery UI 中克隆可拖动对象时,如何将数据和事件传输到新元素?【英文标题】:When cloning a draggable object in jQuery UI, how can you transfer the data and events to the new element? 【发布时间】:2011-09-17 13:13:14 【问题描述】:

我有一个设置了helper: 'clone' 的可拖动元素,但是当它克隆该元素时,data() 或事件都不会在新元素中持久存在。

我尝试了多种方法来重新附加 data(),但我似乎无法在同一语句中选择新元素和旧元素。

例如,我可以在可拖动的stop() 事件中选择初始元素:

$blah.draggable(
    helper: 'clone',
    stop: function(ev, ui) 
        var oldData = $(ev.target).data('blah');
    
);

而且我还可以在 droppable drop() 事件中获取新元素:

$blah.droppable(
    drop : function(ev, ui) 
        var $newElement = ui.draggable;
    
);

但我想不出办法让两者都参加同一个活动。

我想做的是以某种方式传输数据,例如:

$newElement.data('blah', $oldElement.data('blah'));

或者以其他方式使数据持久化,就像你可以使用$blah.clone(true);

【问题讨论】:

【参考方案1】:

要访问 drop 中原始元素的数据,您可以使用 ui.draggable.context。在下面的示例中,上下文将引用原始拖动元素,您可以访问其所有内容。 Draggable 是指被拖放的新元素。

$("#droppable").droppable(
    drop: function(ev, ui)         
        console.log(ui);
        console.log(ui.draggable.context);
        console.log($(ui.draggable.context).data('pic'));
    
);

【讨论】:

我在发布 4 年后才回答这个问题,也许 api 已经改变(我使用的是 JqueryUI 1.11),但我没有看到 ui.draggable 属性,如此处所述。但是,我确实通过$(e.currentTarget.activeElement).closest("#my_container") 找到了对拖动对象的原始容器的引用。没有ui.draggable.context,而是ui.helper.context【参考方案2】:

我没有在 droppable 方面进行过广泛的工作,但你就不能做这样的事情吗?

$(".draggable").draggable(
    helper: 'clone'
);

$("#droppable").droppable(
    drop: function(ev, ui) 
        $(this).append(ui.draggable.clone(true));
    
);

除非我缺少某些东西,否则似乎可以工作:

http://jsfiddle.net/hasrq/

【讨论】:

重新阅读您的问题,ui.draggable 似乎不是您提到的新元素,而是原始元素。 嘿,这真的让我走上了正确的道路,因为事实证明问题是我将它与 sortable() 结合起来,这是问题实际出现的地方。在下面发布我的解决方案。但是非常感谢您对此的帮助! 好吧,如果您使用可排序,这可能会有所帮助:***.com/questions/5788391/…【参考方案3】:

原来问题是可排序的,而不是可拖动/可放置的(我后来附加了可排序的,但认为这不是问题的一部分,所以我把它排除在原始问题之外)。

我最终使用了上面@kingjiv 的解决方案的组合,以及一个不是最好的黑客,但至少它似乎有效:

$blah.sortable(
    receive: function(ev, ui) 
        // setting a global variable here
        MyGlobals.cloneCache = ui.item.clone(true);
    ,
    stop: function(ev, ui) 
        $(ui.item).replaceWith(MyGlobals.cloneCache);
    
);

这个想法是,您首先克隆 receive() 事件中的原始项目,将其缓存在一个变量中,然后用 stop() 事件中的项目替换该项目。

有点难看,但至少它可以工作。

【讨论】:

其实这还有其他问题,因为当你试图拖动重新排序时,它从原始元素中拉出,呃。所以现在我有一个非常可怕的黑客,我在接收中缓存我需要的数据,然后在停止中应用它,但前提是还没有应用另一块“isChanged”数据(或者缓存得到调用并在重新排序时弄乱数据)......超级丑陋但工作afaik 我遇到了同样类型的问题。您能否发布解决您问题的代码?【参考方案4】:

ui.item 指被拖动的项目。克隆拖动项时,没有内置方法可以从receive 函数访问目标项。但是,有一个有点hacky的方法:

$blah.sortable(
    receive: function (ev, ui) 
        var $target = $(this).data().sortable.currentItem;
        var $source = $(ui.sender);
        // now you can copy data from source to target
        $target.data('data-item', $source.data('data-item')); 
     
);

【讨论】:

在最新版本的 jquery-ui 中,您可以通过 ui.helper 访问目标项目

以上是关于在 jQuery UI 中克隆可拖动对象时,如何将数据和事件传输到新元素?的主要内容,如果未能解决你的问题,请参考以下文章

在 jquery drop UI 中,如何使用正确的鼠标位置将拖动元素克隆到放置位置?

Jquery UI 可拖动:如果按下 Ctrl 则克隆

jQuery拖放:克隆的可拖动移动原始

克隆上的jquery ui可拖动停止功能

jquery UI 可拖动助手:克隆从原始中删除可拖动?

拖动时jQuery可拖动克隆大小