我试图让JQuery Sortable工作,但我遇到了轻微的可用性问题。
我尝试排序的列表非常大(约200项)。如果用户尝试将顶部项目向右拖动到底部,则一旦项目到达屏幕可见部分的底部,页面将滚动一小部分,然后停止。要触发更多向下滚动,您必须以圆周运动移动鼠标,直到项目到达底部。
是否有任何方法可以在拖动项目并自动向下滚动屏幕时跟踪鼠标的位置?
答案 0 :(得分:22)
我会看一下scroll, scrollSensativity, and scrollSpeed options。
您可以执行以下操作:
$("#sort").sortable({ scroll: true, scrollSensitivity: 100 });
或
$("#sort").sortable({ scroll: true, scrollSpeed: 100 });
甚至
$("#sort").sortable({ scroll: true, scrollSensitivity: 100, scrollSpeed: 100 });
答案 1 :(得分:6)
当助手项目接近边缘(顶部或底部)时,scrollSensitivity的值控制滚动行为, 如果使用以下代码,则可以在拖动时使用“sort”事件无条件滚动:
$(".sortable").sortable({
scroll: true,
scrollSensitivity: 80,
scrollSpeed: 3,
sort: function(event, ui) {
var currentScrollTop = $(window).scrollTop(),
topHelper = ui.position.top,
delta = topHelper - currentScrollTop;
setTimeout(function() {
$(window).scrollTop(currentScrollTop + delta);
}, 5);
}
});
不确定这是否完全解决了您所看到的问题,但我发现使用此方法可以提高列表的可用性。 这是link to jsfiddle。
答案 2 :(得分:2)
我认为您可以考虑处理外部滚动以进行排序。我建议使用计时器和可排序的'out'事件。
这是基于jQueryUI演示页面的一段代码,你可以用它作为起点,如果想要这样:
$(function() {
var scroll = '';
var $scrollable = $("#sortable");
function scrolling(){
if (scroll == 'up') {
$scrollable.scrollTop($scrollable.scrollTop()-20);
setTimeout(scrolling,50);
}
else if (scroll == 'down'){
$scrollable.scrollTop($scrollable.scrollTop()+20);
setTimeout(scrolling,50);
}
}
$( "#sortable" ).sortable({
scroll:false,
out: function( event, ui ) {
if (!ui.helper) return;
if (ui.offset.top>0) {
scroll='down';
} else {
scroll='up';
}
scrolling();
},
over: function( event, ui ) {
scroll='';
},
deactivate:function( event, ui ) {
scroll='';
}
});
$( "#sortable").disableSelection();
});
以下是工作示例:JSBIN
<强>抱歉强>
我没有锁定示例代码并被偶然销毁。现在又恢复了工作。
答案 3 :(得分:2)
我已从overflow-y: scroll
移除body
以解决此问题。
答案 4 :(得分:2)
我有一个带有bootstrap的响应表,这不会让它工作。
不喜欢这样:
<div class="table-responsive">
<table>
...
</table>
</div>
喜欢这样是:
<table>
...
</table>
并使用以下选项:
答案 5 :(得分:1)
我无法得到任何其他答案。使用Chrome和可排序的网格,当项目被拖动到窗口的顶部或底部边缘时,需要垂直滚动。
注意:这仅适用于滚动整个窗口。如果窗口内有可滚动部分并需要滚动它,则无法使用。
我能够获得以下working flawlessly:
var currentlyScrolling = false;
var SCROLL_AREA_HEIGHT = 40; // Distance from window's top and bottom edge.
$(".sortable").sortable({
scroll: true,
sort: function(event, ui) {
if (currentlyScrolling) {
return;
}
var windowHeight = $(window).height();
var mouseYPosition = event.clientY;
if (mouseYPosition < SCROLL_AREA_HEIGHT) {
currentlyScrolling = true;
$('html, body').animate({
scrollTop: "-=" + windowHeight / 2 + "px" // Scroll up half of window height.
},
400, // 400ms animation.
function() {
currentlyScrolling = false;
});
} else if (mouseYPosition > (windowHeight - SCROLL_AREA_HEIGHT)) {
currentlyScrolling = true;
$('html, body').animate({
scrollTop: "+=" + windowHeight / 2 + "px" // Scroll down half of window height.
},
400, // 400ms animation.
function() {
currentlyScrolling = false;
});
}
}
});
currentlyScrolling = false
SCROLL_AREA_HEIGHT = 40
sort: (event, ui) ->
return if currentlyScrolling
windowHeight = $( window ).height()
mouseYPosition = event.clientY
if mouseYPosition < SCROLL_AREA_HEIGHT # Scroll up.
currentlyScrolling = true
$( 'html, body' ).animate( { scrollTop: "-=" + windowHeight / 2 + "px" }, 400, () -> currentlyScrolling = false )
else if mouseYPosition > ( windowHeight - SCROLL_AREA_HEIGHT ) # Scroll down.
currentlyScrolling = true
$( 'html, body' ).animate( { scrollTop: "+=" + windowHeight / 2 + "px" }, 400, () -> currentlyScrolling = false )
答案 6 :(得分:1)
旧主题,但这是带有自定义可滚动元素的滚动示例
var sortScrollInterval = null;
var scrollDelta = 0;
$('.selector').sortable({
// [..]
scroll: false,
sort: function(event, ui) {
var scrollContainer = $('#container');
var vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
// Scroll top if cursor is into the first 20% of screen
// Scroll bottom if cursor is into the last 20% of screen
var top20 = vh * 0.2;
var bottom20 = vh * 0.8;
if ((ui.position.top <= top20) || (ui.position.top > bottom20)) {
if (ui.position.top <= top20) {
// Closer to the top = quicker scroll
scrollDelta = -40 * ((top20 - ui.position.top) / top20);
}
else {
// Closer to the bottom = quicker scroll
scrollDelta = 40 * (1 - (ui.position.top - bottom20) / bottom20);
}
// Set interval
if (null === sortScrollInterval) {
sortScrollInterval = setInterval(function() {
if (Math.abs(scrollDelta) > 10) {
$(scrollContainer).scrollTop($(scrollContainer).scrollTop() + scrollDelta);
}
}, 50);
}
}
else if (null !== sortScrollInterval) {
clearInterval(sortScrollInterval);
sortScrollInterval = null;
}
},
over: function(event, ui) {
if (null !== sortScrollInterval) {
clearInterval(sortScrollInterval);
sortScrollInterval = null;
}
},
deactivate: function(event, ui) {
if (null !== sortScrollInterval) {
clearInterval(sortScrollInterval);
sortScrollInterval = null;
}
}
});
答案 7 :(得分:0)
您可以根据mouseMove返回的位置触发事件。这是一个简单的教程:http://jquery-howto.blogspot.com/2009/07/identifying-locating-mouse-position-in.html
本教程可能会帮助您入门:http://valums.com/vertical-scrolling-menu/ 这会产生同样的效果:http://www.queness.com/resources/html/scrollmenu/index.html
答案 8 :(得分:0)
根据@marty的回答,这是一个精细调整的代码,它将: 1.控制滚动的速度 2.向下滚动并向上滚动,没有毛刺。 3.默认速度一次为7px 4.将忽略小于7px的运动
var previousLocation, previousDelta;
$( ".selector" ).sortable({
sort: function(event, ui) {
var currentScrollTop = $(window).scrollTop(),
topHelper = ui.position.top,
delta = topHelper - currentScrollTop;
setTimeout(function() {
if((delta < 7 && delta >=0) || (delta > -7 && delta <=0))
return;
if(delta > 7){
delta = 7;
if((topHelper - previousDelta) < previousLocation){
delta = (delta * -1);
}
}
if(delta < -7){
delta = -7;
if((topHelper - previousDelta) > previousLocation){
delta = (delta * -1);
}
}
$(window).scrollTop(currentScrollTop + delta);
previousLocation = topHelper; previousDelta = delta;
}, 5);
}
});