9

这是一个有点晦涩的问题,但我正在使用 jQuery Sortables 并试图让两个连接的列表在一个定位为fixed. 一切正常,直到您稍微滚动页面以使两个列表最终位于彼此之上。然后列表似乎对哪个应该接收被拖动的项目感到困惑,这意味着当它出现/消失在每个列表中时,您会发生一堆抖动。

看起来问题是两个列表都在处理鼠标/排序事件,因为被拖动的项目在技术上是在两个列表上,但我想要的是让覆盖列表(即那个position: fixed)吞下事件,以便底层主list 不会尝试接收该项目。

这是最小的代码示例:

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>
    <style type="text/css">
        ul { list-style-type: none; padding: 0; float: left; }
        li { margin: 5px; padding: 5px; width: 500px; border: solid 1px #F00; background-color: #FFF; }
        #overlayed { position: fixed; top: 0; background-color: #000; margin: 20px; padding: 10px; }
        #overlayed li { width: 50px; float: left; }
    </style>
    <script type="text/javascript">
        $(function() {
            $("ul").sortable({ connectWith: "ul", opacity: 0.6 }).disableSelection();
        });
    </script>
</head>
<body>
<div id="overlayed"> 
    <ul>
        <li>Item X</li>
        <li>Item Y</li>
        <li>Item Z</li>
    </ul>
</div>
<br/><br/><br/><br/><br/>
<ul>
    <li>Item 01</li>
    <li>Item 02</li>
    <li>Item 03</li>
    <li>Item 04</li>
    <li>Item 05</li>
    <li>Item 06</li>
    <li>Item 07</li>
    <li>Item 08</li>
    <li>Item 09</li>
    <li>Item 10</li>
    <li>Item 11</li>
    <li>Item 12</li>
    <li>Item 13</li>
    <li>Item 14</li>
    <li>Item 15</li>
    <li>Item 16</li>
    <li>Item 17</li>
    <li>Item 18</li>
    <li>Item 19</li>
    <li>Item 20</li>
    <li>Item 21</li>
    <li>Item 22</li>
    <li>Item 23</li>
    <li>Item 24</li>
    <li>Item 25</li>
    <li>Item 26</li>
    <li>Item 27</li>
    <li>Item 28</li>
    <li>Item 29</li>
    <li>Item 30</li>
</ul>
</body>
</html>

所以问题是,我该如何解决它?

4

4 回答 4

5

我最终通过扩展内置sortable功能来解决这个问题,以创建一个fixedSortable当有覆盖时检测并选择性地忽略悬停在列表上的功能。出于我的目的,我只是对规则进行了硬编码,因为这适合我的需求/时间限制,但是您应该能够使其完全通用而无需太多努力。

首先是代码(下面的解释):

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>
    <style type="text/css">
        ul { list-style-type: none; padding: 0; float: left; }
        li { margin: 5px; padding: 5px; width: 500px; border: solid 1px #F00; background-color: #FFF; }
        #overlayed { position: fixed; top: 0; background-color: #000; margin: 20px; padding: 10px; }
        #overlayed li { width: 50px; float: left; }
    </style>
    <script type="text/javascript">
        (function ($, undefined) {
            $.widget("ui.fixedSortable", $.ui.sortable, {
                _init: function () {
                    this.element.data("sortable", this.element.data("fixedSortable"));
                    return $.ui.sortable.prototype._init.apply(this, arguments);
                },
                _create:function() {
                    var result = $.ui.sortable.prototype._create.apply(this, arguments);
                    this.containerCache.sortable = this;
                    return result;
                },
                _intersectsWithPointer: function (item) {
//This line....
                    if (item.instance.element.hasClass("main-list") && this.positionAbs.top + this.offset.click.top < $(window).scrollTop() + 87) { 
                        return false;
                    }
                    return $.ui.sortable.prototype._intersectsWithPointer.apply(this, arguments);
                },
                _intersectsWith: function(containerCache) {
//Also this line....
                    if (containerCache.sortable.element.hasClass("main-list") && this.positionAbs.top + this.offset.click.top < $(window).scrollTop() + 87) {
                        return false;
                    }
                    return $.ui.sortable.prototype._intersectsWith.apply(this, arguments);
                }
            });
        })(jQuery);

        $(function() {
            $("ul").fixedSortable({ connectWith: "ul", opacity: 0.6 }).disableSelection();
        });
    </script>
</head>
<body>
<div id="overlayed"> 
    <ul>
        <li>Item X</li>
        <li>Item Y</li>
        <li>Item Z</li>
    </ul>
</div>
<br/><br/><br/><br/><br/>
<ul class="main-list" >
    <li>Item 01</li>
    <li>Item 02</li>
    <li>Item 03</li>
    <li>Item 04</li>
    <li>Item 05</li>
    <li>Item 06</li>
    <li>Item 07</li>
    <li>Item 08</li>
    <li>Item 09</li>
    <li>Item 10</li>
    <li>Item 11</li>
    <li>Item 12</li>
    <li>Item 13</li>
    <li>Item 14</li>
    <li>Item 15</li>
    <li>Item 16</li>
    <li>Item 17</li>
    <li>Item 18</li>
    <li>Item 19</li>
    <li>Item 20</li>
    <li>Item 21</li>
    <li>Item 22</li>
    <li>Item 23</li>
    <li>Item 24</li>
    <li>Item 25</li>
    <li>Item 26</li>
    <li>Item 27</li>
    <li>Item 28</li>
    <li>Item 29</li>
    <li>Item 30</li>
</ul>
</body>
</html>

如果您自己调整它,您需要更改上面标记的两条注释行。item.instance.element基本上,如果悬停在 (和containerCache.sortable.element) 上的项目不是覆盖并且事件 ( this) 发生在覆盖范围内,则 if 语句应该评估为 true(因此返回 false) 。这样,主列表永远不会在覆盖所在页面的位置接收事件。因此,在这段代码中,如果主列表发生在屏幕的前 87 个像素中,则它们不会接收任何事件,因为那是我的固定叠加层所在的位置(在这个简化的示例中不太准确,但希望它仍然有意义)。

于 2010-12-07T00:46:46.490 回答
3

我实现了对 sortable 的更改,以便将 z-index 考虑在内。

在此处查看我的 fork:https ://github.com/david04/jquery-ui/commit/feaf94ebabacee4d11b5e98c412d795d68ca9d51 (10 行代码,相当简单的更改)

您需要compareZIndex=true在调用时添加该选项sortable

于 2014-05-16T13:27:37.783 回答
2

这是我认为您遇到的错误,修复要简单得多:

http://bugs.jqueryui.com/ticket/7065

于 2011-11-18T18:04:31.923 回答
0

我在一个页面上遇到了这个问题,其中一个列表垂直位于第二个列表上方。即使溢出设置为隐藏,顶部列表的看不见的溢出仍然阻止其下方列表的移动事件(这可以通过在顶部列表中将溢出设置为自动以帮助可视化重叠来确认)。这是一个 z-index 问题。

我的解决方法是将此代码放在可排序的停止事件中:

 //expliclty hide the overflow items
 $('.topList .item:gt(5)').hide();
 $('.topeList .item:first').show();

我在这里所做的是显式隐藏顶部列表元素,只留下前 5 个可见,以便顶部和底部列表之间没有 DOM 偏移重叠。

于 2012-05-10T19:17:30.610 回答