96

我有一个带有滚动条的 div,当它到达末尾时,我的页面开始滚动。无论如何我可以阻止这种行为吗?

4

14 回答 14

68

您可以通过执行以下操作来停用整个页面的滚动:

<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>
于 2012-04-18T14:21:18.207 回答
43

找到了解决方案。

http://jsbin.com/itajok

这就是我需要的。

这就是代码。

http://jsbin.com/itajok/edit#javascript,html

使用 jQuery 插件。


由于弃用通知而更新

jquery-mousewheel

delta向事件处理程序添加三个参数( 、deltaX和)的旧行为deltaY现已弃用,并将在以后的版本中删除。

然后,event.deltaY现在必须使用:

var toolbox = $('#toolbox'),
    height = toolbox.height(),
    scrollHeight = toolbox.get(0).scrollHeight;

toolbox.off("mousewheel").on("mousewheel", function (event) {
  var blockScrolling = this.scrollTop === scrollHeight - height && event.deltaY < 0 || this.scrollTop === 0 && event.deltaY > 0;
  return !blockScrolling;
});

演示

于 2012-05-09T10:57:06.470 回答
16

选定的解决方案是一件艺术品。觉得这个插件值得。。。。

$.fn.scrollGuard = function() {
    return this
        .on( 'wheel', function ( e ) {
            var event = e.originalEvent;
            var d = event.wheelDelta || -event.detail;
            this.scrollTop += ( d < 0 ? 1 : -1 ) * 30;
            e.preventDefault();
        });
};    

这一直给我带来不便,与我见过的其他黑客相比,这个解决方案非常干净。很想知道它是如何工作的以及它会得到多么广泛的支持,但是为 Jeevan 和最初提出这个问题的人欢呼。顺便说一句 - stackoverflow 答案编辑器需要这个!

更新

我相信这更好,因为它根本不会尝试操纵 DOM,只会有条件地防止冒泡......

$.fn.scrollGuard2 = function() {
  return this
    .on( 'wheel', function ( e ) {
      var $this = $(this);
      if (e.originalEvent.deltaY < 0) {
        /* scrolling up */
        return ($this.scrollTop() > 0);
      } else {
        /* scrolling down */
        return ($this.scrollTop() + $this.innerHeight() < $this[0].scrollHeight);
      }
    })
  ;
};    

在 chrome 中效果很好,比其他解决方案简单得多......让我知道它在其他地方的表现如何......

小提琴

于 2015-05-07T21:31:35.667 回答
8

您可以在 div 上使用 mouseover 事件来禁用正文滚动条,然后使用 mouseout 事件再次激活它?

例如 HTML

<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();">
    content
</div>

然后像这样的javascript:

var body = document.getElementsByTagName('body')[0];
function disableBodyScroll() {
    body.style.overflowY = 'hidden';
}
function enableBodyScroll() {
    body.style.overflowY = 'auto';
}
于 2012-04-18T14:22:01.383 回答
8

这是在 Y 轴上执行此操作的跨浏览器方法,它适用于桌面和移动设备。在 OSX 和 iOS 上测试。

var scrollArea = this.querySelector(".scroll-area");
scrollArea.addEventListener("wheel", function() {
    var scrollTop = this.scrollTop;
    var maxScroll = this.scrollHeight - this.offsetHeight;
    var deltaY = event.deltaY;
    if ( (scrollTop >= maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
        event.preventDefault();
    }
}, {passive:false});

scrollArea.addEventListener("touchstart", function(event) {
    this.previousClientY = event.touches[0].clientY;
}, {passive:false});

scrollArea.addEventListener("touchmove", function(event) {
    var scrollTop = this.scrollTop;
    var maxScroll = this.scrollHeight - this.offsetHeight;
    var currentClientY = event.touches[0].clientY;
    var deltaY = this.previousClientY - currentClientY;
    if ( (scrollTop >= maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
        event.preventDefault();
    }
    this.previousClientY = currentClientY;
}, {passive:false});
于 2017-07-02T22:23:24.000 回答
8

正如这里所回答的,大多数现代浏览器现在都支持overscroll-behavior: none;CSS 属性,它可以防止滚动链接。就是这样,只有一行!

于 2019-12-13T14:06:28.827 回答
7

我写了解决这个问题

  var div;
  div = document.getElementsByClassName('selector')[0];

  div.addEventListener('mousewheel', function(e) {
    if (div.clientHeight + div.scrollTop + e.deltaY >= div.scrollHeight) {
      e.preventDefault();
      div.scrollTop = div.scrollHeight;
    } else if (div.scrollTop + e.deltaY <= 0) {
      e.preventDefault();
      div.scrollTop = 0;
    }
  }, false);
于 2015-06-30T08:58:19.983 回答
6

如果我正确理解了您的问题,那么当鼠标悬停在 div 上(比如说侧边栏)时,您希望防止滚动主要内容。为此,侧边栏可能不是主要内容的滚动容器(即浏览器窗口)的子项,以防止滚动事件冒泡到其父项。

这可能需要以下列方式进行一些标记更改:

<div id="wrapper"> 
    <div id="content"> 
    </div> 
</div> 
<div id="sidebar"> 
</div> 

查看它在此示例小提琴中的工作,并将其与此示例小提琴进行比较,后者的侧边栏鼠标离开行为略有不同。

另请参阅使用浏览器的主滚动条仅滚动一个特定的 div

于 2012-04-18T14:52:25.533 回答
3

如果您输入选择器元素,这将禁用窗口上的滚动。像魅力一样工作。

elements = $(".selector");

elements.on('mouseenter', function() {
    window.currentScrollTop = $(window).scrollTop();
    window.currentScrollLeft = $(window).scrollTop();
    $(window).on("scroll.prevent", function() {
        $(window).scrollTop(window.currentScrollTop);
        $(window).scrollLeft(window.currentScrollLeft);
    });
});

elements.on('mouseleave', function() {
    $(window).off("scroll.prevent");
});
于 2016-09-03T12:49:11.360 回答
2

您可以通过执行以下操作来停用整个页面的滚动,但显示滚动条!

<div onmouseover="document.body.style.overflow='hidden'; document.body.style.position='fixed';" onmouseout="document.body.style.overflow='auto'; document.body.style.position='relative';"></div>
于 2015-06-17T16:27:37.223 回答
2
$this.find('.scrollingDiv').on('mousewheel DOMMouseScroll', function (e) {
  var delta = -e.originalEvent.wheelDelta || e.originalEvent.detail;
  var scrollTop = this.scrollTop;
  if((delta < 0 && scrollTop === 0) || (delta > 0 && this.scrollHeight - this.clientHeight - scrollTop === 0)) {
    e.preventDefault();
  }
});
于 2015-11-02T19:43:11.517 回答
1

根据 ceed 的回答,这是一个允许嵌套滚动保护元素的版本。只有鼠标悬停的元素会滚动,而且滚动非常流畅。这个版本也是可重入的。它可以在同一个元素上多次使用,并且会正确删除和重新安装处理程序。

jQuery.fn.scrollGuard = function() {
    this
        .addClass('scroll-guarding')
        .off('.scrollGuard').on('mouseenter.scrollGuard', function() {
            var $g = $(this).parent().closest('.scroll-guarding');
            $g = $g.length ? $g : $(window);
            $g[0].myCst = $g.scrollTop();
            $g[0].myCsl = $g.scrollLeft();
            $g.off("scroll.prevent").on("scroll.prevent", function() {
                $g.scrollTop($g[0].myCst);
                $g.scrollLeft($g[0].myCsl);
            });
        })
        .on('mouseleave.scrollGuard', function() {
            var $g = $(this).parent().closest('.scroll-guarding');
            $g = $g.length ? $g : $(window);
            $g.off("scroll.prevent");
        });
};

scroll-guard一种简单的使用方法是向页面中允许滚动的所有元素添加一个类,例如。然后$('.scroll-guard').scrollGuard()用来保护他们。

于 2016-10-12T21:09:20.387 回答
0

如果您应用一种overflow: hidden样式,它应该会消失

编辑:实际上我读错了你的问题,这只会隐藏滚动条,但我认为这不是你要找的。

于 2012-04-18T14:12:59.960 回答
0

我无法得到在 Chrome 和 Firefox 中工作的任何答案,所以我想出了这个合并:

$someElement.on('mousewheel DOMMouseScroll', scrollProtection);

function scrollProtection(event) {
    var $this = $(this);
    event = event.originalEvent;
    var direction = (event.wheelDelta * -1) || (event.detail);
    if (direction < 0) {
        if ($this.scrollTop() <= 0) {
            return false;
        }
    } else {
        if ($this.scrollTop() + $this.innerHeight() >= $this[0].scrollHeight) {
            return false;
        }
    }
}
于 2016-12-10T06:55:02.660 回答