滚动子div滚动窗口,如何停止该窗口?


Answers:


68

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

<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>

33
很好,但是只要您将鼠标悬停在div上,它就会使浏览器的滚动条消失。
cstack 2012年

@cstack你是对的,这就是OP(Jeevan)自己的答案更好的原因。
Imran Bughio 2014年

2
现在,由于用户移动鼠标,许多浏览器滚轮消失并重新出现,因此上述注释不再是问题。
基思·霍利迪

但是,当页面嵌入到iframe中时,此解决方案不起作用。
Gautam Krishnan 2015年

5
不是解决方案。将溢出设置为隐藏会隐藏滚动条,该滚动条会突然重新格式化外部元素的所有内容。同样,这假定外部元素是body,但它可能是另一个滚动div。
robisrob

43

找到了解决方案。

http://jsbin.com/itajok

这就是我所需要的。

这就是代码。

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

使用jQuery插件。


由于弃用通知而更新

jquery-mousewheel

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

然后,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;
});

演示版


6
您的链接将github用于js并中断,因为内容类型等等在这里可行
Michael J. Calkins

这两个jsbin似乎都无法在Chrome设备仿真器和iphone上运行。有人知道这是否仍然有效吗?
Dirk Boer

2
您的“解决方案”仅适用于鼠标滚动事件,不适用于上/下翻页或箭头键。
斯科特

为什么在这里需要“关闭”?
布拉德·约翰逊

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中效果很好,并且比其他解决方案更简单...让我知道它在其他地方的表现如何...

小提琴


3
添加DOMMouseScroll事件使其可与Firefox一起使用→ jsfiddle.net
chodorowicz/

我很惊讶这没有写到jQuery中。我认为主要要点之一是不必关心您使用的浏览器。
robisrob

实际上,似乎两者都已被弃用... wheel事件
robisrob

这会导致Macbook上的Chrome浏览器明显滚动。公认的解决方案不存在此问题。
danvk 2015年

令人失望。有很多不同的版本。似乎是ui的一个重要方面,而且确实如此,这真是令人惊讶,因为它是如此直观。显然,浏览器具备了解内部滚动div的极限,可以将事件应用于窗口,所以为什么没有可用于查询它的句柄?
robisrob

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';
}

12
您也可以使用document.body
Ry-

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});

这很棒!哇,正是我搜索到的。它肯定需要更多的支持。
delato468

此解决方案效果很好,但需要稍作调整:需要更改scrollTop === maxScroll by scrollTop >= maxScroll。这似乎很奇怪,需要1次
tchiot.ludo

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年

+1这是一个可靠的解决方案。如果将其附加到可滚动容器,则本示例中的div为e.currentTarget
马特

非常干净的解决方案。谢谢
Thinh Bui

在Chrome 61.0.3163.100和Safari 11.0中可以正常工作,但在FireFox 56.0(Mac OS El Capitan)中则
无法工作

这是最好的本机解决方案。但是,false无需指定,addEventListener因为这是默认设置。而且,比较应该是简单的不等式(><),而不是>=<=
Quolonel问题

6

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

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

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

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

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


在这种情况下,边栏位于包装div的外部。所以,我不认为会滚动泡到父
杰文

“本案”是指您的案子?如果不是:您完全正确。如果是这样:如果页面在div滚动结束时滚动,则滚动消息会冒泡到div父级,因此我认为您的页面和div不是兄弟姐妹,而是父级和子级。
NGLN 2012年

是的,Page是我的div的父级,因此到达末尾时,它将开始滚动页面,而我不想这样做。
Jeevan

如果您不能使div成为主要内容的兄弟,那么仅靠HTML + CSS不能解决此问题。这是默认行为。
NGLN

1
我认为这是所有提供的答案中最有效的解决方案;凭借页面底部良好的干净标记,只需很少的CSS和JS hack即可获得所需的行为。

6

作为回答这里,最现代的浏览器都支持的overscroll-behavior: none;CSS属性,防止滚动链接。就是这样,只需一行!


2
这应该是2020年的正确答案。对于我的用例,最好的解决方案是overscroll-behavior: contain;
码头

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");
});

这确实是一个可行的解决方案。我需要用纯js语言编写,所以我重新编写了它。如果有人需要,它就在这里。对于仍在寻找解决方案的任何人,您应该在下面查看我的答案。
安德烈·斯托利亚

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>

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();
  }
});

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()来保护他们。


0

如果应用overflow: hidden样式,它应该消失

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


1
我都需要滚动条。我在谈论行为。当我使用鼠标轨迹球滚动到div滚动的末尾时,它一定不能滚动整个页面。
Jeevan

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;
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.