jqueryUI sortable:如何在拖动时强制更新占位符位置

时间:2012-09-24 08:53:17

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

当jQueryUI可排序列表处于拖动操作的中间时,是否有办法强制jQuery更新占位符的位置,即使用户只是水平移动鼠标? (jQuery对垂直可排序的命中测试似乎只在鼠标垂直移动时起作用。)

如果没有可用的文档化解决方案,那么无法解决或者使用可排序,可拖动等内容的解决方案可以作为最后的手段。

以下是更多信息:

如果将项目拖动到垂直jQueryUI可排序列表的右侧,除非您向上或向下移动鼠标,否则列表不会排序。一旦你向上或向下移动鼠标(甚至只是1px!),列表就会排序。示例位于http://jsfiddle.net/f3Lhg/,摘录如下。

这可能看起来像是一个极端情况,但是当连接列表从一个列表侧向拖动到另一个列表时,它实际上很常见。即使整个拖拽不完全水平,前30px-100px可能会导致不可预测的拖拽行为和糟糕的用户体验。即使连接列表出现问题更多,您也可以通过拖出列表并从侧面返回列表轻松地使用单个列表进行复制。

问题不是浏览器特定的。在我测试的所有浏览器上,行为都是相同的。此外,添加tolerance选项无法解决问题。

这是jQueryUI错误还是预期的行为?有没有已知的解决方法?

顺便说一句,在我的应用程序中,我已将列表连接到右侧,因此我无法使用{axis:'y'}选项,因为这会阻止拖动到连接列表。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.js"></script>
    <style type="text/css">
    .sortable { list-style-type: none; width: 400px; }
    .sortable li { margin: 5px 0; padding: 30px; border: 1px solid #999; }
    .sortable li.placeholder { margin: 0; height: 4px; border: 0; padding: 0; background-color: #800; }
    </style>
    <script type="text/javascript">
        $(document).ready(function () {
            $('.sortable').sortable({
                placeholder: 'placeholder'
            }).disableSelection();
        });
    </script>
</head>
<body>
    <ul class="sortable">
        <li>Item #1</li>
        <li>Item #2</li>
        <li>Item #3</li>
        <li>Item #4</li>
        <li>Item #5</li>
    </ul>
</body>
</html>

2 个答案:

答案 0 :(得分:2)

查看jQuery UI source code这似乎是预期的行为。

根据如何设置({1}}属性值,jQuery UI将属性axis设置为布尔标志,以跟踪您的容器是垂直列表还是水平列表(第46行) :

floating

此值用于确定jQuery UI在用户拖动元素时如何处理碰撞检测。

<强>具体地:

方法//Let's determine if the items are being displayed horizontally this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false; (第492行)使用属性_intersectsWithSides来确定您没有在水平列表中拖动,因此返回垂直碰撞结果。如果同时存在垂直拖动方向和元素交集,则垂直碰撞检查仅返回true:

floating

可以通过从if (this.floating && horizontalDirection) { return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); } else { return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf)); } 中的返回条件中删除verticalDirection要求来解决您的问题(它可能还会导致意外的错误行为)。

可替换地:

如果存在垂直或水平拖动,您可以尝试编辑插件的_intersectsWithSides方法以返回true:

_intersectsWithSides

答案 1 :(得分:0)

对不起,也许我在这里误读了一些东西。

你是说问题是,如果你抓住第一个列表项,将它一直向右拖动,从列表中拖出,然后将其拖到第4项,它不会选择相关的结束位置,直到你移动光标至少向上或向下1px?

因为如果是这样的话我根本不认为这是一个严重的可用性问题。我复制了上面描述的例子,它要求我非常小心,以便完全水平移动鼠标。

另外我认为所有用户的本能都是拖动项目并垂直移动而不是水平移动。