我有一个小的“浮动工具箱”-一个div的位置:fixed;溢出:汽车。 工作得很好。

但是当滚动到盒子里面(用鼠标滚轮)并到达底部或顶部时,父元素“接管”“滚动请求”:工具箱后面的文档滚动。 -这是恼人的,而不是用户“要求”。

我正在使用jQuery,并认为我可以用event.stoppropagation()停止这种行为: $(" #工具箱”)。Scroll (function(event){event.stoppropagation()});

它确实进入了函数,但传播仍然发生(文档滚动) 在SO(和谷歌)上搜索这个话题是非常困难的,所以我不得不问: 如何防止滚动事件的传播/冒泡?

编辑: 工作解决方案感谢amustill(和Brandon Aaron的鼠标轮插件在这里: https://github.com/brandonaaron/jquery-mousewheel/raw/master/jquery.mousewheel.js

$(".ToolPage").bind('mousewheel', function(e, d)  
    var t = $(this);
    if (d > 0 && t.scrollTop() === 0) {
        e.preventDefault();
    }
    else {
        if (d < 0 && (t.scrollTop() == t.get(0).scrollHeight - t.innerHeight())) {
            e.preventDefault();
        }
    }
});

当前回答

如果有人还在寻找一个解决方案,下面的插件做的工作http://mohammadyounes.github.io/jquery-scrollLock/

它完全解决了在给定容器内锁定鼠标滚轮滚动的问题,防止它传播到父元素。

不改变滚轮滚动速度,不会影响用户体验。无论操作系统的鼠标滚轮垂直滚动速度如何,你都可以得到相同的行为(在Windows上,它可以设置为一个屏幕或一行,最多100行每个凹槽)。

演示:http://mohammadyounes.github.io/jquery-scrollLock/example/

来源:https://github.com/MohammadYounes/jquery-scrollLock

其他回答

Angular JS指令

我必须封装一个角度指令。以下是其他答案的混搭。在Chrome和Internet Explorer 11上进行了测试。

var app = angular.module('myApp');

app.directive("preventParentScroll", function () {
    return {
        restrict: "A",
        scope: false,
        link: function (scope, elm, attr) {
            elm.bind('mousewheel', onMouseWheel);
            function onMouseWheel(e) {
                elm[0].scrollTop -= (e.wheelDeltaY || (e.originalEvent && (e.originalEvent.wheelDeltaY || e.originalEvent.wheelDelta)) || e.wheelDelta || 0);
                e.stopPropagation();
                e.preventDefault();
                e.returnValue = false;
            }
        }
    }
});

使用

<div prevent-parent-scroll>
    ...
</div>

希望这能帮助下一个从谷歌搜索到这里的人。

我们可以简单地使用CSS。 为子滚动容器元素提供一个样式。

 style="overscroll-behavior: contain"

它不会触发父节点的滚动事件。

我从所选的库中绑定了这个:https://github.com/harvesthq/chosen/blob/master/coffee/chosen.jquery.coffee

function preventParentScroll(evt) {
    var delta = evt.deltaY || -evt.wheelDelta || (evt && evt.detail)
    if (delta) {
        evt.preventDefault()
        if (evt.type ==  'DOMMouseScroll') {
            delta = delta * 40  
        }
        fakeTable.scrollTop = delta + fakeTable.scrollTop
    }
}
var el = document.getElementById('some-id')
el.addEventListener('mousewheel', preventParentScroll)
el.addEventListener('DOMMouseScroll', preventParentScroll)

这对我很有用。

你可以这样尝试:

$('#element').on('shown', function(){ 
   $('body').css('overflow-y', 'hidden');
   $('body').css('margin-left', '-17px');
});

$('#element').on('hide', function(){ 
   $('body').css('overflow-y', 'scroll');
   $('body').css('margin-left', '0px');
});

值得一提的是,在像reactJS, AngularJS, VueJS等现代框架中,当处理固定位置元素时,这个问题有简单的解决方案。例如侧板或叠加元素。

这种技术被称为“传送门”,这意味着应用程序中使用的一个组件,不需要从你正在使用它的地方实际提取它,将在body元素的底部装载它的子元素,在你试图避免滚动的父元素之外。

注意,它不会避免滚动body元素本身。你可以结合这种技术,在滚动div中安装你的应用程序,以达到预期的结果。

React material-ui中的门户实现示例:https://material-ui-next.com/api/portal/