jQuery - 移动元素并返回到精确的先前位置?

7

我正在尝试使用jQuery将一个元素从DOM中的一个位置移动到另一个位置。它的前一个位置可能会有与其相同的元素,那么如何存储它准确的前一个位置,以便它可以返回?以下是一个示例...

<div class="container"></div>
<ul>
    <li></li>
    <li><div class="move">Content</div></li>
    <li></li>
    <li><div class="move">Content</div></li>
    <li></li>
</ul>

“move” div分别通过jQuery .appendTo()移动到“container” div,然后在事件触发时返回其先前位置。如何通过检测它从哪里移动过来(相对于文档的确切位置或另外指定的父容器中的确切位置)来确保每个“move” div返回到其精确的先前位置?

编辑:我已经更正了div上的类,因为我正在处理的特定情况下,列表项是彼此完全相同的副本(结构上),但各自元素中有唯一的内容。另外,将“move” div移回其原始位置的事件是在其中一个按钮被单击时触发的。移动后,该元素如何知道要返回到哪里(具体而言,如何知道列表项中的哪个位置)?


如果您想获得比现有答案更好的答案,您应该更新您的HTML以表示您正在询问的内容。首先,如果您有“与原始容器相同的元素”,那么您可以显示2个容器。如果您的文档“具有列表项完全重复”,请删除它们的唯一类。 - Fabrício Matté
我也想回答你的问题,但是由于这个HTML代码,很难确定你具体期望什么。 - Fabrício Matté
3个回答

4

你可以使用clone函数复制它们,再使用append函数将其添加到目标位置,最后隐藏原始的div,并在需要时remove复制的div并show原始的div。


和我正在打字的完全一样的答案。我认为这是最好的方法。 - Anonymous
1
看起来不错,但是如果 OP 需要迭代所有元素(例如获取数据并发送到另一页),他将不得不添加一个带有 .is(':visible') 的检查。 - Fabrício Matté
1
如果OP试图在div /列表项中复制可排序(http://jqueryui.com/demos/sortable/)功能,或者出于任何原因他想要使用排序后的div /项,我只是做了一些记录,指出可能会有重复元素并需要进行额外检查。 - Fabrício Matté
你的回答对于给定的问题有效,虽然我还无法+1它(我的票数在大约1小时30分钟后UTC重置:P)。 - Fabrício Matté
通过使用 @charles 类,您可以在隐藏元素时添加一个额外的类,例如 hidden。或者您也可以使用 indexeq 方法。 - Ram
显示剩余3条评论

2
在移动元素之前,将其.parent()存储在变量中,然后使用.append().appendTo()在准备好时返回它。

好的回答,我不知道 .parent() 会存储调用它的嵌套元素的相对索引。真的很有用的信息,我也会点赞的。 - Fabrício Matté
我制作了一个fiddle来检查你的代码功能,我相信你的代码在未来会很有用。 - Fabrício Matté
这样做不会奏效,因为根据楼主的问题,"有与源容器相同的元素在其旁边"。仅仅存储父级将无法保留元素在父级中的位置。 - Madbreaks
@Madbreaks 是的,那触及到了主要问题。我想知道,在jQuery中是否有一个基本函数或插件,可以返回元素相对于文档的确切DOM位置?类似于XPath,就像在Firebug中这里是您评论的XPath.../html/body/div[4]/div[2]/div/div[2]/div[2]/div[4]/table/tbody/tr[2]/td[2]/div/table/tbody/tr[3]/td[2]/div/span - Charles
HTML 就是 XML,为什么不使用xpath呢?http://docs.jquery.com/DOM/Traversing/Selectors#XPath_Selectors - Madbreaks
根据您的标记,您可以存储“.next()”元素,然后在将元素移回时执行“.insertBefore()”。 - naton

2
以下是我所做的事情。您的帖子遗漏了一些重要细节,因此我会猜测并希望它们适用于您的情况。
我猜您在元素上有一个单击处理程序,该处理程序将其移动到div中。
CSS:
.placeholder { display:none; }

JS:

var id,
    gid = 0;

$('.move').click(function(e){
    if(!$(this).parents('.container')){
        // Move to container
        id = 'placeholder-' + gid++;
        $(this)
            .before('<div class="placeholder ' + id + '"></div>')  // Save a DOM "bookmark"
            .appendTo('.container')                               // Move the element to container
            .data('placeholder', id);                              // Store it's placeholder's info
    }
    else{
        // Move back out of container
        $(this)
            .appendTo('.placeholder.' + $(this).data('placeholder'))  // Move it back to it's proper location
            .unwrap()                               // Remove the placeholder
            .data('placeholder', undefined);        // Unset placeholder data
     }
 });

点击第一个 div.move 后,您的 HTML 将如下所示:
<div class="container">
    <div class="move>Content</div>
</div>
<ul>
    <li></li>
    <li><div class="placeholder placeholder-0"></div></li>
    <li></li>
    <li><div class="move">Content</div></li>
    <li></li>
</ul>

我已经成功实现了这一点,但上面的代码尚未经过测试。希望它能传达出想法。我喜欢这种方法的原因:

  1. 没有元素的重复(这可能会破坏唯一ID要求,例如)
  2. 最小化DOM影响
  3. 移动项上的事件和处理程序保持完好,但不会被复制

完美吗?不是。但它工作得很好,而且非常干净。你的情况可能会有所不同。

干杯


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接