【问题标题】:JQuery Sortable and automatic scrollingJQuery 可排序和自动滚动
【发布时间】:2010-09-17 22:10:04
【问题描述】:

我正在尝试让 JQuery Sortable 工作,但我遇到了一个轻微的可用性问题。

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

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

【问题讨论】:

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


    【解决方案1】:

    我会看看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 });
    

    【讨论】:

    • 这个答案没有解决问题中实际需要的内容。
    【解决方案2】:

    虽然当帮助项接近边缘(顶部或底部)时,scrollSensitivity 的值控制滚动行为, 如果您使用以下代码,则可以在拖动时使用“排序”事件无条件滚动:

    $(".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

    【讨论】:

    • 如果滚动速度太快(就像我的情况一样),您可以在setTimeout 中添加以下行:if(delta > 7) delta = 7; 并使用数字来调整速度
    • 你有一个bug,向下再向上滚动时,滚动仍然向下
    【解决方案3】:

    当一个项目被拖到接近顶部或底部时滚动窗口。

    我无法得到任何其他答案。使用 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 )
    

    【讨论】:

    • 如果你想改变滚动速度,只需在代码windowHeight / 2 + "px"这两个部分增加数字 2 以使其变慢
    • @SamiBirnbaum 好建议。也许我们应该把它改成一个常数,比如SCROLL_SPEED 什么的?让我知道你的想法。
    【解决方案4】:

    我认为您可以考虑处理可排序外部的滚动。我建议使用 timer 和 sortable 的 '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

    对不起
    我没有锁定示例代码并被意外破坏。现在它又开始工作了。

    【讨论】:

      【解决方案5】:

      我已从 body 中删除 overflow-y: scroll 以解决它。

      【讨论】:

      • 谢谢,删除“overflow-x: initial”和“overflow-y: initial”后工作正常
      【解决方案6】:

      我有一个带引导程序的响应表,这不会让它工作。

      不是这样的:

      <div class="table-responsive">
         <table>
            ...
         </table>
      </div>
      

      像这样是的:

       <table>
         ...
       </table>
      

      并使用这些选项:

      scroll, scrollSensitivity, scrollSpeed

      【讨论】:

        【解决方案7】:

        根据@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);
                }
            });
        

        【讨论】:

          【解决方案8】:

          旧主题,但这里是带有自定义可滚动元素的滚动示例

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

          【讨论】:

            【解决方案9】:

            您可以根据 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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-04-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-11-04
              • 1970-01-01
              相关资源
              最近更新 更多