Scroll the page on drag with jQuery

后端 未结 7 1969
无人及你
无人及你 2020-12-01 02:26

I have tried using kinetic.js and the code below, however when I try this in IE11 it keeps jumping to the top every time I scroll:

$(\"html\").kinetic();


        
相关标签:
7条回答
  • 2020-12-01 02:36

    You can do this quite simply by recording the position of the mouse when clicked, and the current position when being dragged. Try this:

    var clicked = false, clickY;
    $(document).on({
        'mousemove': function(e) {
            clicked && updateScrollPos(e);
        },
        'mousedown': function(e) {
            clicked = true;
            clickY = e.pageY;
        },
        'mouseup': function() {
            clicked = false;
            $('html').css('cursor', 'auto');
        }
    });
    
    var updateScrollPos = function(e) {
        $('html').css('cursor', 'row-resize');
        $(window).scrollTop($(window).scrollTop() + (clickY - e.pageY));
    }
    

    To prevent text selection while dragging, add the following CSS:

    body {
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        -khtml-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
    }
    

    Example fiddle


    Update

    Here's an version of the above as a jQuery plugin, extended to allow both vertical and horizontal scrolling via the settings. It also allows you to change the cursor that's used too.

    (function($) {
      $.dragScroll = function(options) {
        var settings = $.extend({
          scrollVertical: true,
          scrollHorizontal: true,
          cursor: null
        }, options);
    
        var clicked = false,
          clickY, clickX;
    
        var getCursor = function() {
          if (settings.cursor) return settings.cursor;
          if (settings.scrollVertical && settings.scrollHorizontal) return 'move';
          if (settings.scrollVertical) return 'row-resize';
          if (settings.scrollHorizontal) return 'col-resize';
        }
    
        var updateScrollPos = function(e, el) {
          $('html').css('cursor', getCursor());
          var $el = $(el);
          settings.scrollVertical && $el.scrollTop($el.scrollTop() + (clickY - e.pageY));
          settings.scrollHorizontal && $el.scrollLeft($el.scrollLeft() + (clickX - e.pageX));
        }
    
        $(document).on({
          'mousemove': function(e) {
            clicked && updateScrollPos(e, this);
          },
          'mousedown': function(e) {
            clicked = true;
            clickY = e.pageY;
            clickX = e.pageX;
          },
          'mouseup': function() {
            clicked = false;
            $('html').css('cursor', 'auto');
          }
        });
      }
    }(jQuery))
    
    $.dragScroll();
    /* Note: CSS is not relevant to the solution. 
       This is only needed for this demonstration */
    
    body,
    html {
      padding: 0;
      margin: 0;
    }
    
    div {
      height: 1000px;
      width: 2000px;
      border-bottom: 3px dashed #EEE;
      /* gradient is only to make the scroll movement more obvious */
      background: rgba(201, 2, 2, 1);
      background: -moz-linear-gradient(-125deg, rgba(201, 2, 2, 1) 0%, rgba(204, 0, 204, 1) 16%, rgba(94, 0, 201, 1) 31%, rgba(0, 153, 199, 1) 43%, rgba(0, 199, 119, 1) 56%, rgba(136, 199, 0, 1) 69%, rgba(199, 133, 0, 1) 83%, rgba(107, 0, 0, 1) 100%);
      background: -webkit-gradient(left top, right bottom, color-stop(0%, rgba(201, 2, 2, 1)), color-stop(16%, rgba(204, 0, 204, 1)), color-stop(31%, rgba(94, 0, 201, 1)), color-stop(43%, rgba(0, 153, 199, 1)), color-stop(56%, rgba(0, 199, 119, 1)), color-stop(69%, rgba(136, 199, 0, 1)), color-stop(83%, rgba(199, 133, 0, 1)), color-stop(100%, rgba(107, 0, 0, 1)));
      background: -webkit-linear-gradient(-125deg, rgba(201, 2, 2, 1) 0%, rgba(204, 0, 204, 1) 16%, rgba(94, 0, 201, 1) 31%, rgba(0, 153, 199, 1) 43%, rgba(0, 199, 119, 1) 56%, rgba(136, 199, 0, 1) 69%, rgba(199, 133, 0, 1) 83%, rgba(107, 0, 0, 1) 100%);
      background: -o-linear-gradient(-125deg, rgba(201, 2, 2, 1) 0%, rgba(204, 0, 204, 1) 16%, rgba(94, 0, 201, 1) 31%, rgba(0, 153, 199, 1) 43%, rgba(0, 199, 119, 1) 56%, rgba(136, 199, 0, 1) 69%, rgba(199, 133, 0, 1) 83%, rgba(107, 0, 0, 1) 100%);
      background: -ms-linear-gradient(-125deg, rgba(201, 2, 2, 1) 0%, rgba(204, 0, 204, 1) 16%, rgba(94, 0, 201, 1) 31%, rgba(0, 153, 199, 1) 43%, rgba(0, 199, 119, 1) 56%, rgba(136, 199, 0, 1) 69%, rgba(199, 133, 0, 1) 83%, rgba(107, 0, 0, 1) 100%);
      background: linear-gradient(-110deg, rgba(201, 2, 2, 1) 0%, rgba(204, 0, 204, 1) 16%, rgba(94, 0, 201, 1) 31%, rgba(0, 153, 199, 1) 43%, rgba(0, 199, 119, 1) 56%, rgba(136, 199, 0, 1) 69%, rgba(199, 133, 0, 1) 83%, rgba(107, 0, 0, 1) 100%);
      filter: progid: DXImageTransform.Microsoft.gradient( startColorstr='#c90202', endColorstr='#6b0000', GradientType=1);
      color: #EEE;
      padding: 20px;
      font-size: 2em;
    }
    
    body {
      -webkit-touch-callout: none;
      -webkit-user-select: none;
      -khtml-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div>First...</div>
    
    <div>Second...</div>

    0 讨论(0)
  • 2020-12-01 02:36

    I modified Rory's code quite a bit, and I got per-element side scrolling to work. I needed that for a project that had multiple scrollable tiles in a single view for a webapp. Add the .drag class to any element, possibly do a bit of styling, and it should be good to go.

    // jQuery sidescroll code. Can easily be modified for vertical scrolling as well.
    // This code was hacked together so clean it up if you use it in prod.
    // Written by Josh Moore
    // Thanks to Rory McCrossan for a good starting point
    
    // How far away the mouse should move on a drag before interrupting click
    // events (your own code must also interrupt regular click events with a
    // method that calls getAllowClick())
    const THRESHOLD = 32;
    var clicked = false;
    var allowClick = true;
    
    // mouseX: most recent mouse position. updates when mouse moves.
    //     el: jQuery element that will be scrolled.
    //    thX: "threshold X", where the mouse was at the beginning of the drag
    var mouseX, startY, el, thX;
    
    // Add the .drag class to any element that should be scrollable.
    // You may need to also add these CSS rules:
    //   overflow: hidden; /* can be replaced with overflow-x or overflow-y */
    //   whitespace: none;
    function drag() {
        $('.drag').on({
            'mousemove': e => {
                if (el != null && clicked) {
                    el.scrollLeft(el.scrollLeft() + (mouseX - e.pageX));
                    mouseX = e.pageX;
                    allowClick = Math.abs(thX - mouseX) > THRESHOLD ? false : true;
                }
            },
            'mousedown': e => {
                clicked = true;
                // This lets the user click child elements of the scrollable.
                // Without it, you must click the .drag element directly to be able to scroll.
                el = $(e.target).closest('.drag');
                mouseX = e.pageX;
                thX = e.pageX;
            },
            'mouseup': e => {
                clicked = false;
                el = null;
                allowClick = true;
            }
        });
    }
    
    function getAllowClick() {
        return allowClick;
    }
    

    Again, I had no use for vertical scrolling but it would be pretty simple to add (replace X's with Y's, scrollTop() instead of scrollLeft(), etc). Hope this helps someone in the future!

    0 讨论(0)
  • 2020-12-01 02:39

    Based on the first answer, this is the code for horizontal scroll on mouse drag:

    var clicked = false, clickX;
    $(document).on({
        'mousemove': function(e) {
            clicked && updateScrollPos(e);
        },
        'mousedown': function(e) {
            e.preventDefault();        
            clicked = true;
            clickX = e.pageX;
        },
        'mouseup': function() {
            clicked = false;
            $('html').css('cursor', 'auto');
        }
    });
    
    var updateScrollPos = function(e) {
        $('html').css('cursor', 'grabbing');
        $(window).scrollLeft($(window).scrollLeft() + (clickX - e.pageX));
    }
    
    0 讨论(0)
  • 2020-12-01 02:44

    I just like to add. Using Rory's code I made horizontal scrolling.

    var clicked = false, base = 0;
    
    $('#someDiv').on({
        mousemove: function(e) {
            clicked && function(xAxis) {
                var _this = $(this);
                if(base > xAxis) {
                    base = xAxis;
                    _this.css('margin-left', '-=1px');
                }
                if(base < xAxis) {
                    base = xAxis;
                    _this.css('margin-left', '+=1px');
                }
            }.call($(this), e.pageX);
        },
        mousedown: function(e) {
            clicked = true;
            base = e.pageX;
        },
        mouseup: function(e) {
            clicked = false;
            base = 0;
        }
    });
    
    0 讨论(0)
  • 2020-12-01 02:44

    This code will work on horizontal and vertical mouse drag scroll. It's pretty simple.

    var curYPos = 0,
        curXPos = 0,
        curDown = false;
    
    window.addEventListener('mousemove', function(e){ 
      if(curDown === true){
        window.scrollTo(document.body.scrollLeft + (curXPos - e.pageX), document.body.scrollTop + (curYPos - e.pageY));
      }
    });
    
    window.addEventListener('mousedown', function(e){ curDown = true; curYPos = e.pageY; curXPos = e.pageX; });
    window.addEventListener('mouseup', function(e){ curDown = false; }); 
    
    0 讨论(0)
  • 2020-12-01 02:47

    This framework is written in vanilla javascript, and worked best for me.

    It also supports scroller inside divs.

    Note: If you create dynamic content, call dragscroll.reset(); after render.

    dragscroll

    Usage

    demo

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