JQuery Sortable and automatic scrolling

后端 未结 9 2271
走了就别回头了
走了就别回头了 2021-02-05 10:02

I am trying to get JQuery Sortable to work but I have run into a slight usability problem.

The list that I am trying to sort is quite large (about 200 items). If the

相关标签:
9条回答
  • 2021-02-05 10:20

    I would take a look at the scroll, scrollSensativity, and scrollSpeed options.

    You can do something like:

    $("#sort").sortable({ scroll: true, scrollSensitivity: 100 });
    

    or

    $("#sort").sortable({ scroll: true, scrollSpeed: 100 });
    

    or even

    $("#sort").sortable({ scroll: true, scrollSensitivity: 100, scrollSpeed: 100 });
    
    0 讨论(0)
  • 2021-02-05 10:20

    Scroll window when an item is dragged close to the top or bottom.

    I could not get any of the other answers working. Using Chrome and a sortable grid that needs to scroll vertically when an item is being dragged to the top or bottom edge of the window.

    NOTE: This only works for scrolling the entire window. This will not work if you have a scrollable section inside of the window and need to scroll that.

    I was able to get the following 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 )
    
    0 讨论(0)
  • 2021-02-05 10:23

    I have removed overflow-y: scroll from body to resolve it.

    0 讨论(0)
  • 2021-02-05 10:24

    You can trigger events based on the position returned by mouseMove. Here's a simple tutorial: http://jquery-howto.blogspot.com/2009/07/identifying-locating-mouse-position-in.html

    This tutorial might help you get started: http://valums.com/vertical-scrolling-menu/ And this walks through the same effect: http://www.queness.com/resources/html/scrollmenu/index.html

    0 讨论(0)
  • 2021-02-05 10:25

    Based on @marty 's answer, here is a fine tuned code that will: 1. Control speed of the scrolling 2. Will scroll down and scroll up without glitches. 3. Default speed is 7px at a time 4. movements of less than 7px will be ignored

    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);
            }
        });
    
    0 讨论(0)
  • 2021-02-05 10:28

    I think that you can consider handling scrolling external to sortable. I suggest to use timer and 'out' event of sortable.

    Here is piece of code based on jQueryUI demo page, you can use it as start point, if want to go this way:

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

    Here is also working example: JSBIN

    sorry
    I did not lock example code and was destroyed incidentally. Now it's back to work.

    0 讨论(0)
提交回复
热议问题