这是一个模糊不清的问题,但是我正在使用jQuery Sortables并试图让两个连接列表在一个定位为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>
所以问题是,我该如何解决?
答案 0 :(得分: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
如果您自己进行调整,则需要更改上面标记的两条注释行。基本上if语句应该评估为true(因此返回false)如果项目悬停在(containerCache.sortable.element
和this
)上不覆盖和事件({{ 1}})发生在叠加层的范围内。这样,主列表永远不会在覆盖所在的页面位置接收事件。因此,在此代码中,如果主列表出现在屏幕的前87个像素中,则主列表不会接收任何事件,因为那是我的固定叠加层所在的位置(在这个愚蠢的示例中这不太准确,但希望它仍然有意义)。
答案 1 :(得分:3)
我将更改实施为可排序,以便将z-index考虑在内。
请在此处查看我的分叉:https://github.com/david04/jquery-ui/commit/feaf94ebabacee4d11b5e98c412d795d68ca9d51 (10行代码,非常简单的改动)
调用compareZIndex=true
时,您需要添加sortable
选项。
答案 2 :(得分:2)
这是我认为你遇到的错误,而且解决方法更简单:
答案 3 :(得分:0)
我在一个页面上遇到了这个问题,我在第二个列表的垂直上方有一个列表。即使溢出被设置为隐藏,顶部列表的看不见的溢出仍然阻止其下方列表的移动事件(这可以通过在顶部列表中设置溢出到自动来帮助可视化重叠来确认)。这是一个z指数问题。
我的修复是将此代码放在可排序的停止事件中:
//expliclty hide the overflow items
$('.topList .item:gt(5)').hide();
$('.topeList .item:first').show();
我在这里做的是显式隐藏顶部列表元素,只留下前5个可见,以便顶部和底部列表之间没有DOM偏移重叠。