使用jQuery处理多列可排序项目

3
这是我的困境 - 我有一个由两列元素(使用<div>进行样式设置)组成的列表,我需要使它们可排序。对于在一列或另一列中的元素,这很容易 - 我只需设置两列,将我的元素置于它们最初应该在的位置,标记它们为“可排序”,然后让jQuery完成其魔术。
然而,在列表中我有两个需要跨越两个列的元素。不幸的是,这破坏了模型的可用性。如果我坚持使用标准的两列设置,我会遇到宽元素重叠或与另一列中的元素相互错位的情况。
我也尝试迭代两列以重新定位元素,以便不会重叠,但后来我意识到另一个问题:我的第二列(右边的列)不知道在左侧列中定位的元素。
以下是我的标记的简化示例:
<div id="wrapper">
    <div id="column-1" class="column" style="width:400px;">
        <div id="item-1" class="item" style="width:200px;">
        ...
        </div>
        <div id="item-2" class="item wide" style="width:400px;">
        ...
        </div>
        <div id="item-3" class="item" style="width:200px;">
        ...
        </div>
    </div>
    <div id="column-2" class="column">
        <div id="item-4" class="item" style="width:200px;">
        ...
        </div>
        <div id="item-5" class="item" style="width:200px;">
        ...
        </div>
    </div>
</div>

这个应该对齐的方式类似于这张表格:
-------------------
| item 1 | item 4 |
|      item 2     |
| item 3 | item 5 |
-------------------

每个项目都可以被拖放到其他位置,1、3、4、5项之间可以在两列之间互换,2号项目可以根据需要上下移动。实际上,您也应该能够得到类似这样的结果:

-------------------
| item 1 |        |
|      item 2     |
| item 3 | item 5 |
| item 4 |        |
-------------------

然而,使用标准列模型(即来自多天谷歌搜索的唯一资源 - jQuery示例和我迄今为止的所有尝试),这种方法行不通。

那么,我该如何使用jQuery UI Sortable插件实现这种布局,以便继续构建我的用户界面呢?

1个回答

3

我投入了更多时间并且已经通过一种可能的解决方案进行了尝试。它仍然存在问题,但至少我获得了大部分所需的功能。

诀窍是创建多个可排序元素并将它们嵌套起来。因此,我的文档结构变成了:

<div id="wrapper">
<div id="macro-section-1" class="macro fixed" style="width:400px">
    <div class="column" style="width:400px;">
        <div id="item-1" class="item" style="width:200px;">
            ...
        </div>
    </div>
    <div class="column">
        <div id="item-4" class="item" style="width:200px;">
        ...
        </div>
    </div>
</div>
<div id="item-2" class="item wide macro mobile" style="width:400px;">
....
</div>
<div id="macro-section-2" class="macro fixed" style="width:400px;">
    <div class="column" style="width:400px;">
        <div id="item-3" class="item" style="width:200px;">
        ...
        </div>
    </div>
    <div class="column">
        <div id="item-5" class="item" style="width:200px;">
        ...
        </div>
    </div>
</div>
</div>

然后,您需要实例化2个不同的sortable——一个用于将较小的1列元素彼此排序,另一个用于对1列“宏”元素进行排序。请注意,此页面上有3个宏元素:
  1. 第一个宏元素是“固定的”,有两列用于较小的可排序元素
  2. 第二个宏元素是“移动的”,这意味着它也将是可排序的
  3. 第三个宏元素是“固定的”,有两列用于较小的可排序元素
使所有这些代码协同工作的代码非常简单:
$('.column').sortable({
    forcePlaceholderSize: true,
    connectWith: '.column',
    handle: '.section-handle',
    cursor: 'move',
    opacity: 0.7
});

$('#wrapper').sortable({
    forcePlaceholderSize: true,
    handle: '.section-handle',
    cursor: 'move',
    opacity: 0.7
});

这将连接各种.column元素,以便可以在页面上的任何位置交换1列元素。第二个代码块将整个#wrapper元素变成自己的可排序元素,这样您就可以重新定位页面上的大型2列元素。

由于我明确声明了拖动手柄(每个可排序元素都附有section-handle类的div),因此您不需要在sortable()调用中使用cancel属性...“fixed”宏元素本身没有拖动手柄,因此无法手动重新定位。但是,您可以毫不费力地将“mobile”宏元素(item-2)拖到页面的任何其他位置。

我仍然面临的唯一问题(更多是个人挫折而不是其他任何事情)是两个可排序元素(#wrapper.column)彼此不知道。所以如果您具有以下布局:

-------------------
| item 1 |        |
|      item 2     |
| item 3 | item 5 |
| item 4 |        |
-------------------

如果项目3、4和5在同一个可排序容器中,那么你就不能将项目2拖到项目3和4之间。当拖动项目2时,页面会意识到3个可排序元素——包含项目1的块、你正在拖动的块(项目2)以及包含项目3、4和5的块。因此,尽管从可用性角度来看,你应该能够将项目2放在项目3和5下面...但我上面概述的方法不允许你这样做。
所以现在它可以工作,但肯定有极大的改进空间。

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