在jQuery中使用多列可排序项

时间:2010-10-11 20:48:15

标签: jquery jquery-ui jquery-ui-sortable

这是我的困境 - 我有一个两列的元素列表(样式为<div> s),我需要对它进行排序。对于存在于一列或另一列中的元素,这很容易 - 我只需设置两列,将我的元素放在最初需要的位置,将它们标记为“可排序”,让jQuery发挥其魔力。

但是,我在列表中有两个元素需要跨越两个列。不幸的是,这打破了模型的可用性。如果我坚持使用我的标准2列设置,我会遇到宽元素与其他列中的元素重叠或重叠的情况。

我也尝试迭代两列来重新定位元素,这样就没有重叠了,但后来我意识到了另一个问题:我的第二列(右边)不知道位于第一列的元素(左边) )。

以下是我的标记的简要示例:

<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示例,我可以在几天的Google搜索中找到的唯一资源,以及我迄今为止所做的每一次尝试)都无效。

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

1 个答案:

答案 0 :(得分: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个不同的可排序项 - 一个用于对较小的1列元素进行排序,另一个用于对1列“宏”元素进行排序。请注意,此页面上有3个宏元素:

  1. 第一个宏元素是“固定的”,有两列用于较小的可排序
  2. 第二个宏元素是“移动”,意味着它也是一个可排序的
  3. 第三个宏元素是“固定的”,有两列用于较小的可排序
  4. 使这一切能够协同工作的代码非常简单:

    $('.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),因此cancel调用不需要sortable()属性...“固定”宏元素没有开始的拖动句柄,因此无法手动重新定位它们。但是,您可以将“移动”宏元素(item-2)拖到页面上的任何其他位置,而不会出现任何问题。

    我仍然面临的唯一问题(并且它比其他任何事情更令人沮丧)是两个可排序的(#wrapper.column)彼此不了解。因此,如果您有以下布局:

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

    项目3,4和5在同一个可排序的容器中,然后你不能在项目3和4之间拖动项目2.当拖动项目2时,页面知道3个可排序的元素 - 包含的块第1项,您正在拖动的块(第2项),以及包含第3,4和5项的块。因此,从可用性角度来看,能够将第2项放在第3项下面5 ...我上面概述的方法不允许你这样做。

    所以现在它起作用,但这里肯定有很大的改进空间。