代码之家  ›  专栏  ›  技术社区  ›  Alconja

处理重叠的jQuery可排序列表

  •  9
  • Alconja  · 技术社区  · 14 年前

    这是一个有点晦涩的问题,但是我使用jQuery排序表,并试图让两个连接的列表在一个被定位为 fixed

    问题似乎是两个列表都在处理鼠标/排序事件,因为从技术上讲,被拖动的项都在两个列表上,但我想要的是覆盖列表(即 position: fixed 一)吞咽事件,这样底层主列表就不会试图接收该项。

    下面是最小代码示例:

    <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 回复  |  直到 14 年前
        1
  •  5
  •   Alconja    13 年前

    我最终通过扩展内置的方法来修复这个问题。 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 )在覆盖范围内发生。这样主列表就不会在覆盖所在的页面位置接收事件。因此,在这段代码中,如果主列表出现在屏幕的前87个像素处,则不会接收任何事件,因为这就是我的固定覆盖(在这个简化的示例中,这不太准确,但希望它仍然有意义)。

        2
  •  3
  •   David Antunes    10 年前

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

    请看我的叉子: https://github.com/david04/jquery-ui/commit/feaf94ebabacee4d11b5e98c412d795d68ca9d51 (10行代码,非常简单的更改)

    compareZIndex=true 打电话时 sortable

        3
  •  2
  •   Jason    12 年前

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

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

        4
  •  0
  •   zomf    12 年前

    我的修复方法是将此代码放入可排序的停止事件:

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