简体   繁体   English

选择移动到Div之外时停止滚动

[英]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: 我有一个div,我想通过鼠标滚轮/滚动条滚动,点击并拖动,所以我添加了一个鼠标监听器来处理它:

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. 但是,当你拖动并将鼠标移出div时,浏览器的行为就像你正在选择文本而“帮助”开始滚动另一种方式以允许你选择更多,即使我禁用了文本选择,我找不到办法让它停下来。

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

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/ https://jsfiddle.net/vej2fkdf/4/

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: 基于caspian的答案,我对其进行了修改,以便不会删除滚动条(看起来很糟糕),而是记录当前滚动位置,然后重复重置滚动位置,直到鼠标重新进入div或释放鼠标为止:

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/ 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... 仍然不完美,因为有一段时间用户将鼠标悬停在滚动条上,浏览器拖动选择正在进行但是在mouseleave触发之前(在你离开滚动条之前它不会触发),所以有一点时间滚动,但它并没有那么糟糕......

In the fiddle, I didn't have issues with the text problems, but perhaps, depending on your browser, you'll need to update the user select also with those compatible with other browsers? 在小提琴中,我没有文本问题的问题,但也许,根据您的浏览器,您还需要更新用户选择与其他浏览器兼容的那些?

-webkit-user-select: none;  /* Chrome all / Safari all */
-moz-user-select: none;     /* Firefox all */
-ms-user-select: none;      /* IE 10+ */
user-select: none; 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM