rfa*_*ams 27 jquery jquery-ui jquery-ui-sortable
我创建了一个演示:http://pastebin.me/584b9a86d715c9ba85b7bebf0375e237
当滚动条位于底部并拖动项目以对其进行排序时,会导致滚动条向上跳跃.它似乎在FF,Safari,Chrome和IE(至少IE8)中这样做.
在我的Mac上的Firefox中,当滚动条位于底部时它会跳起来,但也会在整个列表中添加一个漂亮的闪存.它只是在向上滚动整个列表时闪烁.我相信,如果我弄清楚是什么导致向上滚动(如果我可以阻止它),闪烁也将停止.
我不喜欢它跳起来像那样的b/c我发现它很刺耳和混乱.我知道这是一个角落的案例,但如果可以,我想解决它.
那么,有没有办法防止它向上滚动?或者,是什么导致它向上滚动?
谢谢
小智 47
问题很简单.
首先让我们设置场景.您有一个可排序元素列表,您的页面高于您的屏幕,因此它有一个滚动条,您的页面位于最底部,滚动条一直向下.
问题是,你去拖动一个元素,导致jQuery从dom中删除它然后添加一个占位符.让它慢下来,它首先删除元素,现在列表更短,导致页面更短,导致滚动条更短.然后它添加了占位符,现在页面更长,现在srollbar更长(但是窗口没有向下滚动,所以看起来滚动条跳了起来).
我发现抵消这种情况的最好方法是确保可排序列表具有静态高度,因此删除元素不会导致它变短.这样做的一种方法是
create:function(){
jQuery(this).height(jQuery(this).height());
}
Run Code Online (Sandbox Code Playgroud)
在创建可排序列表时会调用上面的内容,静态地将其高度设置为当前高度.
如果您在其中一个可排序元素中有图片,则除非您预先定义标记中的尺寸,否则上述代码将无法使用.原因是当调用并设置height()时,它在图像填写之前进行计算.没有尺寸,那么图像就没有空间.一旦图像加载,它将占用空间.
这是一种必须定义尺寸的方法.每次检测到要加载的图像时,只需调整列表高度即可.
create:function(){
var list=this;
jQuery(list).find('img').load(function(){
jQuery(list).height(jQuery(list).height());
});
}
Run Code Online (Sandbox Code Playgroud)
最终版本:
jQuery(document).ready(function(){
jQuery("div#todoList").sortable({
handle:'img.moveHandle',
opacity: 0.6,
cursor: 'move',
tolerance: 'pointer',
forcePlaceholderSize: true,
update:function(){
jQuery("body").css('cursor','progress');
var order = jQuery(this).sortable('serialize');
jQuery.post("/ajax.php?do=sort&"+order,function(data){jQuery("body").css('cursor','default');});
},
create:function(){
var list=this;
var resize=function(){
jQuery(list).css("height","auto");
jQuery(list).height(jQuery(list).height());
};
jQuery(list).height(jQuery(list).height());
jQuery(list).find('img').load(resize).error(resize);
}
});
});
Run Code Online (Sandbox Code Playgroud)
pet*_*ket 22
我在使用div容器和div元素时遇到了同样的问题,并且设置容器高度对我没有帮助,但在包含div上显式设置overflow:auto css属性确实解决了问题.仅在Chrome中测试过.
Jon*_*han 13
我也遇到过这个问题.当列表指示页面的长度时会发生这种情况.当您开始排序时,列表高度会瞬间变化,从而导致页面跳转.这是一个奇怪但非常实用的解决方案:
$('ul').height($('ul').height());
Run Code Online (Sandbox Code Playgroud)
大声笑,这样看起来仍然没有修补4年后.这是门票.
添加到@Carl M. Gregory的答案,为了充分利用动态容器而不是将其设置在固定高度,我将编辑jquery.ui.sortable.js核心文件.
只需this._createPlaceHolder...
在第208 行之前移回第228 行.this.helper.css("position", "absolute");
感谢本田在jquery门票网站上.我使用的是Sortable.js版本1.10.3.
卡尔·格雷格里(Carl M. Gregory)完美地解释了这个问题,但是我认为他的解决方案不必要地复杂。
将列表高度设置为固定值可以解决此问题,但是在创建列表时进行此操作还为时过早。您可以使用.mousedown()功能在开始排序之前设置高度。到此时,任何潜在的图像都已加载,因此无需检查其大小。
因此不会发生跳转,但是现在请考虑以下事项:您具有多个连接列表,并且它们是垂直排列的。现在,这发生了:
auto因此,在某个时候,您应该将其高度恢复为auto。什么时候?On mouseup为时已晚(请参阅https://jsfiddle.net/937vv4tx/1/),但是可以,您可以在跳转不再构成威胁之后立即返回正确的值。使用start()活动
更新:但是您仍然想将高度设置为auto开,.mouseup()因为如果您只是单击项目而不开始拖动,由于.mousedown()它已经发生,它仍然会设置固定高度。
$('.sortable').mousedown(function() {
// set fixed height to prevent scroll jump
// when dragging from bottom
$(this).height($(this).height());
}).mouseup(function () {
// set height back to auto
// when user just clicked on item
$(this).height('auto');
}).sortable({
connectWith: '.sortable',
placeholder: 'placeholder',
start: function() {
// dragging is happening
// and scroll jump was prevented,
// we can set it back to auto
$(this).height('auto');
}
});
Run Code Online (Sandbox Code Playgroud)
这段代码非常适合我。