JQuery可排序和自动滚动

时间:2010-09-17 22:10:04

标签: jquery jquery-ui jquery-ui-sortable

我试图让JQuery Sortable工作,但我遇到了轻微的可用性问题。

我尝试排序的列表非常大(约200项)。如果用户尝试将顶部项目向右拖动到底部,则一旦项目到达屏幕可见部分的底部,页面将滚动一小部分,然后停止。要触发更多向下滚动,您必须以圆周运动移动鼠标,直到项目到达底部。

是否有任何方法可以在拖动项目并自动向下滚动屏幕时跟踪鼠标的位置?

9 个答案:

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

并使用以下选项:

scrollscrollSensitivityscrollSpeed

答案 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;
        });

      }
    }
});

Coffeescript Version

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);
        }
    });