Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop Scrolling When Selection Moves Outside Div

I have a div that I want to be scrollable via mousewheel/scrollbars and by clicking and dragging, so I added a mouse listener to handle it:

container
  .mousedown(function() {
  container.css({
    'cursor': 'move',
    "user-select": "none" //disable selecting text
  });
  container.on('mousemove', function(e) {
    if(lastE) {
      container.scrollLeft(container.scrollLeft() - (e.pageX-lastE.pageX));
      container.scrollTop(container.scrollTop() - (e.pageY-lastE.pageY));
    }
    lastE=e;
  })
})
  .mouseup(function() {
  container.off('mousemove');
  container.css({
    'cursor': 'auto',
    "user-select": "default"
  });
  lastE=undefined;
});

However, when you're dragging and you mouse out of the div, the browser acts like you're selecting text and 'helpfully' starts scrolling the other way to allow you to select more, even though I have text selection disabled, and I can't find a way to make it stop.

https://jsfiddle.net/vej2fkdf/

like image 206
zacaj Avatar asked Oct 16 '25 20:10

zacaj


2 Answers

You can try setting the overflow to hidden. It removes the scrollbars, but it DOES prevent the issue you're seeing. You can even do this only when the mouse enters/leaves

var lastE; //last event, used for comparing mouse position
var container = $('#container');
var out = false;

container
  .mousedown(function() {
  container.css({
    'cursor': 'move',
    "user-select": "none" //disable selecting text
  });
  container.on('mousemove', function(e) {
    if(lastE) {
      container.scrollLeft(container.scrollLeft() - (e.pageX-lastE.pageX));
      container.scrollTop(container.scrollTop() - (e.pageY-lastE.pageY));
    }
    lastE=e;
  });
  container.mouseleave(function () {
    container.css({
      'cursor': 'move',
      'overflow':'hidden',
      "user-select": "none" //disable selecting text
    });
  });
  container.mouseenter(function () {
    container.css({
      'cursor': 'move',
      'overflow':'scroll',
      "user-select": "none" //disable selecting text
    });
  });
})

$(document).mouseup(function() {
  container.off('mousemove');
  container.off('mouseleave');
  container.off('mouseenter');
  container.css({
    'cursor': 'auto',
    "user-select": "default",
    "overflow": "scroll"
  });
  lastE=undefined;
});

https://jsfiddle.net/vej2fkdf/4/

like image 67
caspian Avatar answered Oct 19 '25 11:10

caspian


Based on caspian's answer, I modified it so that instead of removing the scrollbars (which looks bad), it records the current scroll position and then repeatedly resets the scroll position until the mouse reenters the div or the mouse is released:

var mouseLeftX;
var mouseLeftY;

container
  .mousedown(function() {
    container.css({
      'cursor': 'move',
      "user-select": "none" //disable selecting text
    });
    container.on('mousemove', function(e) {
      if(lastE) {
        container.scrollLeft(container.scrollLeft() - (e.pageX-lastE.pageX));
        container.scrollTop(container.scrollTop() - (e.pageY-lastE.pageY));
      }
      lastE=e;
    });
    container.mouseleave(function () {
      mouseLeftX = container.scrollLeft();
      mouseLeftY = container.scrollTop();
      container.scroll(function() {
       if(lastE) {
          container.scrollLeft(mouseLeftX);
          container.scrollTop(mouseLeftY);
        }
      })
    });
    container.mouseenter(function () {
        container.off('scroll');
      container.css({
        'cursor': 'move',
        "user-select": "none" //disable selecting text
      });
    });
  })

$(document).mouseup(function() {
  container.off('mousemove');
  container.off('mouseleave');
  container.off('mouseenter');
  container.off('scroll');
  container.css({
    'cursor': 'auto',
    "user-select": "default",
  });
  lastE=undefined;
});

https://jsfiddle.net/vej2fkdf/5/

Still not perfect, as there is a time as the user is mousing over the scrollbars where the browser drag-to-select is going but before mouseleave fires (it doesn't fire until you leave the scrollbar), so there is a bit of scrolling, but it's not as bad...

like image 22
zacaj Avatar answered Oct 19 '25 09:10

zacaj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!