Javascript 处理重叠的jQuery可排序列表

Javascript 处理重叠的jQuery可排序列表,javascript,jquery,drag-and-drop,jquery-ui-sortable,fixed,Javascript,Jquery,Drag And Drop,Jquery Ui Sortable,Fixed,这是一个有点模糊的问题,但我正在使用jQuery排序表,并尝试在将一个列表定位为fixed时使两个连接的列表能够很好地协同工作。在您稍微滚动页面,使两个列表最终位于彼此的顶部之前,一切正常。然后,列表似乎会混淆哪些人应该接收被拖动的项目,这意味着当它在每个列表中出现/消失时,会出现一系列的抖动 问题似乎是两个列表都在处理鼠标/排序事件,因为从技术上讲,要拖动的项目位于两个列表之上,但我希望覆盖的列表(即位置:fixedone)吞下事件,以便底层主列表不会尝试接收项目 下面是最简单的代码示例: &

这是一个有点模糊的问题,但我正在使用jQuery排序表,并尝试在将一个列表定位为
fixed
时使两个连接的列表能够很好地协同工作。在您稍微滚动页面,使两个列表最终位于彼此的顶部之前,一切正常。然后,列表似乎会混淆哪些人应该接收被拖动的项目,这意味着当它在每个列表中出现/消失时,会出现一系列的抖动

问题似乎是两个列表都在处理鼠标/排序事件,因为从技术上讲,要拖动的项目位于两个列表之上,但我希望覆盖的列表(即
位置:fixed
one)吞下事件,以便底层主列表不会尝试接收项目

下面是最简单的代码示例:

<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>

ul{列表样式类型:无;填充:0;浮点:左;}
li{边距:5px;填充:5px;宽度:500px;边框:实心1px#F00;背景色:#FFF;}
#重叠{位置:固定;顶部:0;背景色:#000;边距:20px;填充:10px;}
#重叠li{宽度:50px;浮动:左;}
$(函数(){
$(“ul”).sortable({connectWith:“ul”,不透明度:0.6});
});
  • 项目十
  • 项目Y
  • 项目Z







  • 项目01
  • 项目02
  • 项目03
  • 项目04
  • 项目05
  • 项目06
  • 项目07
  • 项目08
  • 项目09
  • 项目10
  • 项目11
  • 项目12
  • 项目13
  • 项目14
  • 项目15
  • 项目16
  • 项目17
  • 项目18
  • 项目19
  • 项目20
  • 项目21
  • 项目22
  • 项目23
  • 项目24
  • 项目25
  • 项目26
  • 项目27
  • 项目28
  • 项目29
  • 项目30

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

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

首先是代码(解释如下):


ul{列表样式类型:无;填充:0;浮点:左;}
li{边距:5px;填充:5px;宽度:500px;边框:实心1px#F00;背景色:#FFF;}
#重叠{位置:固定;顶部:0;背景色:#000;边距:20px;填充:10px;}
#重叠li{宽度:50px;浮动:左;}
(函数($,未定义){
$.widget(“ui.fixedSortable”,$.ui.sortable{
_init:函数(){
this.element.data(“可排序的”),this.element.data(“可固定排序的”);
返回$.ui.sortable.prototype.\u init.apply(这是参数);
},
_创建:函数(){
var result=$.ui.sortable.prototype.\u create.apply(这是参数);
this.containerCache.sortable=此;
返回结果;
},
_intersectsWithPointer:函数(项){
//这条线。。。。
if(item.instance.element.hasClass(“主列表”)&&this.positionAbs.top+this.offset.click.top<$(window.scrollTop()+87){
返回false;
}
返回$.ui.sortable.prototype.\u intersectsWithPointer.apply(这是参数);
},
_intersectsWith:函数(containerCache){
//还有这一行。。。。
if(containerCache.sortable.element.hasClass(“主列表”)和&this.positionAbs.top+this.offset.click.top<$(窗口).scrollTop()+87){
返回false;
}
返回$.ui.sortable.prototype.\u与.apply相交(这是参数);
}
});
})(jQuery);
$(函数(){
$(“ul”).fixedSortable({connectWith:“ul”,不透明度:0.6}).disableSelection();
});
  • 项目十
  • 项目Y
  • 项目Z







  • 项目01
  • 项目02
  • 项目03
  • 项目04
  • 项目05
  • 项目06
  • 项目07
  • 项目08
  • 项目09
  • 项目10
  • 项目11
  • 项目12
  • 项目13
  • 项目14
  • 项目15
  • 项目16
  • 项目17
  • 项目18
  • 项目19
  • 项目20
  • 项目21
  • 项目22
  • 项目23
  • 项目24
  • 项目25
  • 项目26
  • 项目27
  • 项目28
  • 项目29
  • 项目30
如果您自己修改,您需要更改上面标记的两行注释。基本上,如果悬停的项(
item.instance.element
containerCache.sortable.element
)不是覆盖,并且事件(
this
)发生在覆盖范围内,则if语句的计算结果应为true(从而返回false)。这样,主列表就不会在覆盖所在的页面位置接收事件。因此,在这段代码中,如果事件发生在屏幕的前87个像素上,主列表不会收到任何事件,因为这就是我的固定覆盖(在这个简化的示例中,这不是很准确,但希望它仍然是
<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>
 //expliclty hide the overflow items
 $('.topList .item:gt(5)').hide();
 $('.topeList .item:first').show();