我有一个小的“浮动工具箱”-一个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();
        }
    }
});

当前回答

我从所选的库中绑定了这个: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)

这对我很有用。

其他回答

这是一个简单的JavaScript版本:

function scroll(e) {
  var delta = (e.type === "mousewheel") ? e.wheelDelta : e.detail * -40;
  if (delta < 0 && (this.scrollHeight - this.offsetHeight - this.scrollTop) <= 0) {
    this.scrollTop = this.scrollHeight;
    e.preventDefault();
  } else if (delta > 0 && delta > this.scrollTop) {
    this.scrollTop = 0;
    e.preventDefault();
  }
}
document.querySelectorAll(".scroller").addEventListener("mousewheel", scroll);
document.querySelectorAll(".scroller").addEventListener("DOMMouseScroll", scroll);

作为变量,为了避免滚动或鼠标滚轮处理的性能问题,你可以使用如下代码:

css:

body.noscroll {
    overflow: hidden;
}
.scrollable {
    max-height: 200px;
    overflow-y: scroll;
    border: 1px solid #ccc;
}

html:

<div class="scrollable">
...A bunch of items to make the div scroll...
</div>
...A bunch of text to make the body scroll...

js:

var $document = $(document),
    $body = $('body'),
    $scrolable = $('.scrollable');

$scrolable.on({
          'mouseenter': function () {
            // add hack class to prevent workspace scroll when scroll outside
            $body.addClass('noscroll');
          },
          'mouseleave': function () {
            // remove hack class to allow scroll
            $body.removeClass('noscroll');
          }
        });

工作示例:http://jsbin.com/damuwinarata/4

mouseweel事件的简单解决方案:

$('.element').bind('mousewheel', function(e, d) {
    console.log(this.scrollTop,this.scrollHeight,this.offsetHeight,d);
    if((this.scrollTop === (this.scrollHeight - this.offsetHeight) && d < 0)
        || (this.scrollTop === 0 && d > 0)) {
        e.preventDefault();
    }
});

有es6跨浏览器+移动香草js决定:

function stopParentScroll(selector) {
    let last_touch;
    let MouseWheelHandler = (e, selector) => {
        let delta;
        if(e.deltaY)
            delta = e.deltaY;
        else if(e.wheelDelta)
            delta = e.wheelDelta;
        else if(e.changedTouches){
            if(!last_touch){
                last_touch = e.changedTouches[0].clientY;
            }
            else{
                if(e.changedTouches[0].clientY > last_touch){
                    delta = -1;
                }
                else{
                    delta = 1;
                }
            }
        }
        let prevent = function() {
            e.stopPropagation();
            e.preventDefault();
            e.returnValue = false;
            return false;
        };

        if(selector.scrollTop === 0 && delta < 0){
            return prevent();
        }
        else if(selector.scrollTop === (selector.scrollHeight - selector.clientHeight) && delta > 0){
            return prevent();
        }
    };

    selector.onwheel = e => {MouseWheelHandler(e, selector)}; 
    selector.onmousewheel = e => {MouseWheelHandler(e, selector)}; 
    selector.ontouchmove  = e => {MouseWheelHandler(e, selector)};
}

这在AngularJS中是有效的。 在Chrome和Firefox上测试。

.directive('stopScroll', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            element.bind('mousewheel', function (e) {
                var $this = $(this),
                    scrollTop = this.scrollTop,
                    scrollHeight = this.scrollHeight,
                    height = $this.height(),
                    delta = (e.type == 'DOMMouseScroll' ?
                    e.originalEvent.detail * -40 :
                        e.originalEvent.wheelDelta),
                    up = delta > 0;

                var prevent = function() {
                    e.stopPropagation();
                    e.preventDefault();
                    e.returnValue = false;
                    return false;
                };

                if (!up && -delta > scrollHeight - height - scrollTop) {
                    // Scrolling down, but this will take us past the bottom.
                    $this.scrollTop(scrollHeight);
                    return prevent();
                } else if (up && delta > scrollTop) {
                    // Scrolling up, but this will take us past the top.
                    $this.scrollTop(0);
                    return prevent();
                }
            });
        }
    };
})