2

I have custom buttons that replaces the browser scrollbar. The idea is so that scrolling oversize elements in a page wouldn't result to a dozen scroll bar on a page.

See: https://jsfiddle.net/bwgxs6ng/

Since I must show some code sample (according to some SO error message), see this:

$('.right').on('click', function(event) {
   var target = $(".image-container");
   var current_x = target.scrollLeft();

   if( target.length ) {
      event.preventDefault();
      $(target).animate({
         scrollLeft: current_x+100
      }, 500);
   }
});

It's very simple, basically it takes current scroll position of the parent, and add x to it based on the direction that's clicked.

However, going further, I want it to imitate the hold and continuous scroll, but I'm not sure how to do it.

1) What is the mouse hold event called? (OK, this part is answered, it's called MouseDown as someone point out of the duplicate)

2) What is the continuous scrolling called, and how can I do something that'd imitate the browser's continuous scroll?

CleverNode
  • 307
  • 4
  • 12
  • 1
    possible duplicate of [Jquery: mousedown effect (while left click is held down)](http://stackoverflow.com/questions/3977091/jquery-mousedown-effect-while-left-click-is-held-down) – imtheman Sep 10 '15 at 18:10
  • @imtheman : that can at most answer question 1... I still need question 2 answered – CleverNode Sep 10 '15 at 18:13

2 Answers2

1

you need to set an interval on mousedown, and clear the interval on mouseup, as done in this fiddle for left and right.

The relevant code change is that we removed the click event and replaced it with

$('.left').on('mousedown', function(event) {
        ... scroll code ...
        interval = setInterval(function(){
        ... scroll code ...
        },500);
    })
    .on('mouseup',function(){clearInterval(interval);});
DrunkWolf
  • 994
  • 1
  • 6
  • 18
1

You can just call .animate() repeatedly (with easing set to linear, for smooth movement) inside your setInterval() callback. Just arrange for the interval to be equal to the animation duration, so that the next animation starts just when the previous one ends.

Or, better yet, make the interval shorter (say, 50 ms or less) and just call .prop() instead of .animate(), effectively performing your own animation. (This is how jQuery implements animation internally, anyway.)

Anyway, here's how I'd rewrite your code to support smooth continuous scrolling:

var speed_x = 0, speed_y = 0;
var timer = null;
var target = $(".image-container");

function scroll() {
    if (speed_x == 0 && speed_y == 0) return;
    var current_x = target.scrollLeft();
    var current_y = target.scrollTop();            
    target.prop({
        scrollLeft: current_x - speed_x,
        scrollTop:  current_y - speed_y
    });
}

$('.control').on('mouseover mouseout', function (event) {
    var $this = $(this);
    var speed = (event.type == 'mouseover' ? 10 : 0)
    if ($this.hasClass('left'))  speed_x = +speed;
    if ($this.hasClass('right')) speed_x = -speed;
    if ($this.hasClass('up'))    speed_y = +speed;
    if ($this.hasClass('down'))  speed_y = -speed;
}).on( 'mousedown', function () {
    scroll();
    if (timer !== null) clearInterval(timer);
    timer = setInterval(scroll, 50);
    return false;
});
$(document).on('mouseup', function () {
    if (timer !== null) clearInterval(timer);
    timer = null;
});

Note how the animation is started and stopped in the mousedown and mouseup handlers, but the direction of movement is set on mouseover and mouseout. This allows you to change the scrolling direction while holding the mouse down, by dragging the cursor from one edge to another.

(For bonus points, add divs with e.g. class="control up left" in the corners of the scroll area, so that holding the mouse down over those corners will allow you to scroll diagonally. The JS code above already supports it.)

Ilmari Karonen
  • 49,047
  • 9
  • 93
  • 153