当内部元素滚动位置到达顶部/底部时,防止父元素滚动? [重复]

|                                                                                                                   这个问题已经在这里有了答案:                                                      
已邀请:
使用Brandon Aaron的Mousewheel插件是可能的。 这是一个演示:http://jsbin.com/jivutakama/edit?html,js,output     
我添加此答案是出于完整性考虑,因为@amustill接受的答案不能正确解决Internet Explorer中的问题。请查看我的原始帖子中的评论以获取详细信息。此外,此解决方案不需要任何插件-仅需要jQuery。 本质上,代码通过处理handling0ѭ事件来工作。每个此类事件都包含一个
wheelDelta
,它等于将滚动区域移动到的
px
的数量。如果此值为is3ѭ,那么我们将滚动
up
。如果
wheelDelta
<0
,那么我们滚动
down
。 FireFox:FireFox使用
DOMMouseScroll
作为事件,并填充
originalEvent.detail
,其
+/-
与上述内容相反。它通常返回
3
的间隔,而其他浏览器则以intervals12ѭ的间隔返回滚动(至少在我的机器上)。要更正,我们只需检测它并乘以
-40
即可归一化。 如果
<div>
的可滚动区域已在顶部或底部最大位置,则@amustill的答案通过取消事件来起作用。但是,在“ 15”大于剩余可滚动空间的情况下,Internet Explorer会忽略取消的事件。 换句话说,如果您有一个
200px
高的
<div>
包含
500px
可滚动内容,而当前
scrollTop
400
,则
mousewheel
事件告诉浏览器进一步滚动scroll22ѭ会导致
<div>
<body>
滚动,因为
400
+
120
>
500
。 所以-要解决该问题,我们必须做一些稍微不同的事情,如下所示: 必需的
jQuery
代码是:
$(document).on(\'DOMMouseScroll mousewheel\', \'.Scrollable\', function(ev) {
    var $this = $(this),
        scrollTop = this.scrollTop,
        scrollHeight = this.scrollHeight,
        height = $this.innerHeight(),
        delta = (ev.type == \'DOMMouseScroll\' ?
            ev.originalEvent.detail * -40 :
            ev.originalEvent.wheelDelta),
        up = delta > 0;

    var prevent = function() {
        ev.stopPropagation();
        ev.preventDefault();
        ev.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();
    }
});
从本质上讲,此代码取消了任何会产生不必要边缘条件的滚动事件,然后使用jQuery将
<div>
中的
scrollTop
设置为最大值或最小值,具体取决于
mousewheel
事件所请求的方向。 由于在这两种情况下事件都被完全取消,因此它根本不会传播到“ 33”,因此解决了IE以及所有其他浏览器中的问题。 我还在jsFiddle上提出了一个工作示例。     
我知道这是一个很老的问题,但是由于这是google的顶级结果之一...我不得不以某种方式取消没有jQuery的滚动冒泡,并且此代码对我有用:
function preventDefault(e) {
  e = e || window.event;
  if (e.preventDefault)
    e.preventDefault();
  e.returnValue = false;  
}

document.getElementById(\'a\').onmousewheel = function(e) { 
  document.getElementById(\'a\').scrollTop -= e. wheelDeltaY; 
  preventDefault(e);
}
    
编辑:CodePen示例 对于AngularJS,我定义了以下指令:
module.directive(\'isolateScrolling\', function () {
  return {
    restrict: \'A\',
      link: function (scope, element, attr) {
        element.bind(\'DOMMouseScroll\', function (e) {
          if (e.detail > 0 && this.clientHeight + this.scrollTop == this.scrollHeight) {
            this.scrollTop = this.scrollHeight - this.clientHeight;
            e.stopPropagation();
            e.preventDefault();
            return false;
          }
          else if (e.detail < 0 && this.scrollTop <= 0) {
            this.scrollTop = 0;
            e.stopPropagation();
            e.preventDefault();
            return false;
          }
        });
        element.bind(\'mousewheel\', function (e) {
          if (e.deltaY > 0 && this.clientHeight + this.scrollTop >= this.scrollHeight) {
            this.scrollTop = this.scrollHeight - this.clientHeight;
            e.stopPropagation();
            e.preventDefault();
            return false;
          }
          else if (e.deltaY < 0 && this.scrollTop <= 0) {
            this.scrollTop = 0;
            e.stopPropagation();
            e.preventDefault();
            return false;
          }

          return true;
        });
      }
  };
});
然后将其添加到可滚动元素(下拉菜单ul)中:
<div class=\"dropdown\">
  <button type=\"button\" class=\"btn dropdown-toggle\">Rename <span class=\"caret\"></span></button>
  <ul class=\"dropdown-menu\" isolate-scrolling>
    <li ng-repeat=\"s in savedSettings | objectToArray | orderBy:\'name\' track by s.name\">
      <a ng-click=\"renameSettings(s.name)\">{{s.name}}</a>
    </li>
  </ul>
</div>
在Chrome和Firefox上进行了测试。当在滚动区域的顶部或底部附近(但不在顶部)进行大的鼠标滚轮移动时,Chrome的平滑滚动克服了这一缺陷。     
该线程中提供的所有解决方案均未提及解决现有问题的一种本机方法,无需重新排序DOM和/或使用事件预防技巧。但是有一个很好的理由:这种方式是专有的-仅在MS Web平台上可用。引用MSDN:   -ms-scroll-chaining属性-指定在操作过程中用户达到滚动限制时发生的滚动行为。属性值:      已链接-初始值。当用户在操作期间达到滚动限制时,最接近的可滚动父元素开始滚动。没有显示反弹效果。      none-当用户在操作过程中达到滚动限制时,会显示反弹效果。 当然,此属性仅在IE10 + / Edge上受支持。不过,这是一个有说服力的报价:   为了让您了解防止滚动链接的流行程度,   根据我的快速http归档搜索\“-ms-scroll-chaining:none \”   尽管在30万个页面中   功能,仅在IE / Edge上受支持。 现在,好消息,大家!从Chrome 63开始,我们终于也有了基于Blink平台的本地解决方案-这既是Chrome(显然)又是Android WebView(很快)。 引用介绍性文章:   overscroll-behavior属性是控制CSS的新功能   过度滚动容器时发生的行为   (包括页面本身)。您可以使用它来取消滚动链接,   禁用/自定义拉动刷新功能,禁用橡皮筋   对iOS的影响(当Safari实现过度滚动行为时),等等。[...]      该属性采用三个可能的值:      自动-默认。源自元素的滚动可能会传播到   祖先元素。      包含-防止滚动链接。卷轴不   传播到祖先,但显示了节点内的局部效果。   例如,Android上的   iOS上的橡皮筋效果,当用户点击   滚动边界。注意:使用overscroll-behavior:包含在html上   元素可防止过度滚动导航操作。      none-与contains相同,但是它还可以防止节点自身内部发生过度滚动效果(例如Android过度滚动发光或iOS橡皮筋)。      [...]最好的部分是使用过度滚动行为不会产生不利影响   像介绍中提到的骇客一样影响页面性能! 这是此功能的实际应用。这是相应的CSS模块文档。 更新:自版本59起,Firefox已加入该俱乐部,并且MS Edge有望在版本18中实现此功能。这是相应的功能。     
那里有很多这样的问题,有很多答案,但是我找不到一个不涉及事件,脚本,插件等的令人满意的解决方案。我想直接使用HTML和CSS。我终于找到了一个可行的解决方案,尽管它涉及重组标记以破坏事件链。 1.基本问题 如果某些模态元素是可滚动的,则应用于模态元素的滚动输入(即:mousewheel)将溢出到祖先元素中,并沿相同方向滚动: (所有示例均应在台式机分辨率下查看) https://jsfiddle.net/ybkbg26c/5/ HTML:
<div id=\"parent\">
  <div id=\"modal\">
    This text is pretty long here.  Hope fully, we will get some scroll bars.
  </div>
</div>
CSS:
#modal {
  position: absolute;
  height: 100px;
  width: 100px;
  top: 20%;
  left: 20%;
  overflow-y: scroll;
}
#parent {
  height: 4000px;
}
2.模态滚动中没有父滚动 祖先结束滚动的原因是滚动事件冒泡,并且链上的某些元素能够处理它。停止的一种方法是确保链上的所有元素都不知道如何处理滚动。根据我们的示例,我们可以重构树以将模态移出父元素。由于晦涩的原因,仅保留父代和模式DOM兄弟是不够的。父级必须由建立新堆栈上下文的另一个元素包装。一个绝对定位的包装器可以解决这个问题。 我们得到的结果是,只要模式接收到滚动事件,该事件就不会冒泡到\“ parent \”元素。 通常应该可以重新设计DOM树以支持此行为,而不会影响最终用户看到的内容。 https://jsfiddle.net/0bqq31Lv/3/ HTML:
<div id=\"context\">
  <div id=\"parent\">
  </div>
</div>
<div id=\"modal\">
  This text is pretty long here.  Hope fully, we will get some scroll bars.
</div>
CSS(仅限新功能):
#context {
  position: absolute;
  overflow-y: scroll;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
3.除了滚动模式以外,其他任何地方都没有滚动 上面的解决方案仍然允许父级接收滚动事件,只要它们没有被模式窗口拦截(即,如果光标不在模式上时由鼠标滚轮触发)。有时这是不可取的,并且我们可能希望在模式启动时禁止所有背景滚动。为此,我们需要在模式后面插入一个覆盖整个视口的额外堆栈上下文。我们可以通过显示一个绝对定位的叠加层来做到这一点,如果需要的话可以完全透明(但不是
visibility:hidden
)。 https://jsfiddle.net/0bqq31Lv/2/ HTML:
<div id=\"context\">
  <div id=\"parent\">
  </div>
</div>
<div id=\"overlay\">  
</div>
<div id=\"modal\">
  This text is pretty long here.  Hope fully, we will get some scroll bars.
</div>
CSS(#2之上的新功能):
#overlay {
  background-color: transparent;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
    
作为变体,为避免使用
scroll
mousewheel
处理性能问题,可以使用以下代码: 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     
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>
希望这对下一个通过Google搜索到达这里的人有所帮助。     
这是普通的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);
    
使用本机元素滚动属性和mousewheel插件的delta值:
$elem.on(\'mousewheel\', function (e, delta) {
    // Restricts mouse scrolling to the scrolling range of this element.
    if (
        this.scrollTop < 1 && delta > 0 ||
        (this.clientHeight + this.scrollTop) === this.scrollHeight && delta < 0
    ) {
        e.preventDefault();
    }
});
    
如果有人仍在寻找解决方案,则以下插件可以完成此任务http://mohammadyounes.github.io/jquery-scrollLock/ 它完全解决了将鼠标滚轮锁定在给定容器内的问题,从而防止其传播到父元素。 它不会改变滚轮滚动速度,不会影响用户体验。并且无论OS鼠标滚轮的垂直滚动速度如何,您都会得到相同的行为(在Windows上,可以将其设置为一个屏幕或一行,每行最多100行)。 演示:http://mohammadyounes.github.io/jquery-scrollLock/example/ 资料来源:https://github.com/MohammadYounes/jquery-scrollLock     
amustill作为淘汰赛处理者的答案:
ko.bindingHandlers.preventParentScroll = {
    init: function (element, valueAccessor, allBindingsAccessor, context) {
        $(element).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();
                }
            }
        });
    }
};
    
上面的方法不是很自然,经过一番谷歌搜索之后,我找到了一个更好的解决方案,并且不需要jQuery。参见[1]和演示[2]。
  var element = document.getElementById(\'uf-notice-ul\');

  var isMacWebkit = (navigator.userAgent.indexOf(\"Macintosh\") !== -1 &&
    navigator.userAgent.indexOf(\"WebKit\") !== -1);
  var isFirefox = (navigator.userAgent.indexOf(\"firefox\") !== -1);

  element.onwheel = wheelHandler; // Future browsers
  element.onmousewheel = wheelHandler; // Most current browsers
  if (isFirefox) {
    element.scrollTop = 0;
    element.addEventListener(\"DOMMouseScroll\", wheelHandler, false);
  }
  // prevent from scrolling parrent elements
  function wheelHandler(event) {
    var e = event || window.event; // Standard or IE event object

    // Extract the amount of rotation from the event object, looking
    // for properties of a wheel event object, a mousewheel event object 
    // (in both its 2D and 1D forms), and the Firefox DOMMouseScroll event.
    // Scale the deltas so that one \"click\" toward the screen is 30 pixels.
    // If future browsers fire both \"wheel\" and \"mousewheel\" for the same
    // event, we\'ll end up double-counting it here. Hopefully, however,
    // cancelling the wheel event will prevent generation of mousewheel.
    var deltaX = e.deltaX * -30 || // wheel event
      e.wheelDeltaX / 4 || // mousewheel
      0; // property not defined
    var deltaY = e.deltaY * -30 || // wheel event
      e.wheelDeltaY / 4 || // mousewheel event in Webkit
      (e.wheelDeltaY === undefined && // if there is no 2D property then 
        e.wheelDelta / 4) || // use the 1D wheel property
      e.detail * -10 || // Firefox DOMMouseScroll event
      0; // property not defined

    // Most browsers generate one event with delta 120 per mousewheel click.
    // On Macs, however, the mousewheels seem to be velocity-sensitive and
    // the delta values are often larger multiples of 120, at 
    // least with the Apple Mouse. Use browser-testing to defeat this.
    if (isMacWebkit) {
      deltaX /= 30;
      deltaY /= 30;
    }
    e.currentTarget.scrollTop -= deltaY;
    // If we ever get a mousewheel or wheel event in (a future version of)
    // Firefox, then we don\'t need DOMMouseScroll anymore.
    if (isFirefox && e.type !== \"DOMMouseScroll\") {
      element.removeEventListener(\"DOMMouseScroll\", wheelHandler, false);
    }
    // Don\'t let this event bubble. Prevent any default action.
    // This stops the browser from using the mousewheel event to scroll
    // the document. Hopefully calling preventDefault() on a wheel event
    // will also prevent the generation of a mousewheel event for the
    // same rotation.
    if (e.preventDefault) e.preventDefault();
    if (e.stopPropagation) e.stopPropagation();
    e.cancelBubble = true; // IE events
    e.returnValue = false; // IE events
    return false;
  }
这实际上在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();
                }
            });
        }
    };
})
    
我有类似的情况,这是我的解决方法: 我所有的可滚动元素都使该类可滚动。
$(document).on(\'wheel\', \'.scrollable\', function(evt) {
  var offsetTop = this.scrollTop + parseInt(evt.originalEvent.deltaY, 10);
  var offsetBottom = this.scrollHeight - this.getBoundingClientRect().height - offsetTop;

  if (offsetTop < 0 || offsetBottom < 0) {
    evt.preventDefault();
  } else {
    evt.stopImmediatePropagation();
  }
});
stopImmediatePropagation()确保不要从可滚动子区域滚动父可滚动区域。 这是它的原始JS实现: http://jsbin.com/lugim/2/edit?js,输出     
新的Web开发人员在这里。在IE和Chrome上,这对我来说都是一种魅力。
static preventScrollPropagation(e: HTMLElement) {
    e.onmousewheel = (ev) => {
        var preventScroll = false;
        var isScrollingDown = ev.wheelDelta < 0;
        if (isScrollingDown) {
            var isAtBottom = e.scrollTop + e.clientHeight == e.scrollHeight;
            if (isAtBottom) {
                preventScroll = true;
            }
        } else {
            var isAtTop = e.scrollTop == 0;
            if (isAtTop) {
                preventScroll = true;
            }
        }
        if (preventScroll) {
            ev.preventDefault();
        }
    }
}
不要让行数愚弄您,这很简单-只是为了提高可读性而有些冗长(自我记录代码ftw对吗?) 我还要提到的是,这里的语言是TypeScript,但是与往常一样,将其转换为JS很简单。     
对于使用MooTools的用户,以下是等效代码:
            \'mousewheel\': function(event){
            var height = this.getSize().y;
            height -= 2;    // Not sure why I need this bodge
            if ((this.scrollTop === (this.scrollHeight - height) && event.wheel < 0) || 
                (this.scrollTop === 0 && event.wheel > 0)) {
                event.preventDefault();
            }
请记住,我和其他人一样,必须将值调整px,即-= 2的高度。 基本上,主要的区别在于,在MooTools中,增量信息来自event.wheel,而不是传递给事件的额外参数。 另外,如果我将此代码绑定到任何东西,我也会遇到问题(绑定函数的event.target.scrollHeight不等于非绑定函数的this.scrollHeight) 希望这对某人有所帮助,就像这篇文章对我有所帮助;)     
我的jQuery插件:
$(\'.child\').dontScrollParent();

$.fn.dontScrollParent = function()
{
    this.bind(\'mousewheel DOMMouseScroll\',function(e)
    {
        var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail;

        if (delta > 0 && $(this).scrollTop() <= 0)
            return false;
        if (delta < 0 && $(this).scrollTop() >= this.scrollHeight - $(this).height())
            return false;

        return true;
    });
}
    
查看Leland Kwong的代码。 基本思想是将wheeling事件绑定到child元素,然后使用child元素的本机javascript属性
scrollHeight
和jquery属性
outerHeight
检测滚动的结束,然后将
return false
绑定到wheeling事件以防止滚动。
var scrollableDist,curScrollPos,wheelEvent,dY;
$(\'#child-element\').on(\'wheel\', function(e){
  scrollableDist = $(this)[0].scrollHeight - $(this).outerHeight();
  curScrollPos = $(this).scrollTop();
  wheelEvent = e.originalEvent;
  dY = wheelEvent.deltaY;
  if ((dY>0 && curScrollPos >= scrollableDist) ||
      (dY<0 && curScrollPos <= 0)) {
    return false;
  }
});
    
我从选定的库中获取了这一信息: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)
这对我有用。     
jQuery插件,可模拟Internet Explorer的自然滚动
  $.fn.mousewheelStopPropagation = function(options) {
    options = $.extend({
        // defaults
        wheelstop: null // Function
        }, options);

    // Compatibilities
    var isMsIE = (\'Microsoft Internet Explorer\' === navigator.appName);
    var docElt = document.documentElement,
        mousewheelEventName = \'mousewheel\';
    if(\'onmousewheel\' in docElt) {
        mousewheelEventName = \'mousewheel\';
    } else if(\'onwheel\' in docElt) {
        mousewheelEventName = \'wheel\';
    } else if(\'DOMMouseScroll\' in docElt) {
        mousewheelEventName = \'DOMMouseScroll\';
    }
    if(!mousewheelEventName) { return this; }

    function mousewheelPrevent(event) {
        event.preventDefault();
        event.stopPropagation();
        if(\'function\' === typeof options.wheelstop) {
            options.wheelstop(event);
        }
    }

    return this.each(function() {
        var _this = this,
            $this = $(_this);
        $this.on(mousewheelEventName, function(event) {
            var origiEvent = event.originalEvent;
            var scrollTop = _this.scrollTop,
                scrollMax = _this.scrollHeight - $this.outerHeight(),
                delta = -origiEvent.wheelDelta;
            if(isNaN(delta)) {
                delta = origiEvent.deltaY;
            }
            var scrollUp = delta < 0;
            if((scrollUp && scrollTop <= 0) || (!scrollUp && scrollTop >= scrollMax)) {
                mousewheelPrevent(event);
            } else if(isMsIE) {
                // Fix Internet Explorer and emulate natural scrolling
                var animOpt = { duration:200, easing:\'linear\' };
                if(scrollUp && -delta > scrollTop) {
                    $this.stop(true).animate({ scrollTop:0 }, animOpt);
                    mousewheelPrevent(event);
                } else if(!scrollUp && delta > scrollMax - scrollTop) {
                    $this.stop(true).animate({ scrollTop:scrollMax }, animOpt);
                    mousewheelPrevent(event);
                }
            }
        });
    });
};
https://github.com/basselin/jquery-mousewheel-stop-propagation/blob/master/mousewheelStopPropagation.js     
我能找到的最佳解决方案是侦听窗口上的滚动事件,如果子div可见,则将scrollTop设置为上一个scrollTop。
prevScrollPos = 0
$(window).scroll (ev) ->
    if $(\'#mydiv\').is(\':visible\')
        document.body.scrollTop = prevScrollPos
    else
        prevScrollPos = document.body.scrollTop
如果您触发许多滚动事件,则子div的背景中会出现闪烁,因此可以对其进行调整,但是几乎没有注意到,这对于我的用例来说已经足够了。     
不要在ѭ33上使用ѭ67。它会自动将所有内容滚动到顶部。也不需要JavaScript。利用
overflow: auto;
: HTML结构
<div class=\"overlay\">
    <div class=\"overlay-content\"></div>
</div>

<div class=\"background-content\">
    lengthy content here
</div>
造型
.overlay{
    position: fixed;
    top: 0px;
    left: 0px;
    right: 0px;
    bottom: 0px;
    background-color: rgba(0, 0, 0, 0.8);

    .overlay-content {
        height: 100%;
        overflow: scroll;
    }
}

.background-content{
    height: 100%;
    overflow: auto;
}
在此处播放演示。     
当鼠标悬停在可滚动元素上时,还有一个有趣的技巧可以锁定父级的
scrollTop
。这样,您就不必实现自己的滚轮滚动。 这是防止文档滚动的示例,但是可以针对任何元素进行调整。
scrollable.mouseenter(function ()
{
  var scroll = $(document).scrollTop();
  $(document).on(\'scroll.trap\', function ()
  {
    if ($(document).scrollTop() != scroll) $(document).scrollTop(scroll);
  });
});

scrollable.mouseleave(function ()
{
  $(document).off(\'scroll.trap\');
});
    
M.K.提供了一个很棒的插件。插件可以在这里找到。但是,为了完整起见,我认为将其组合为AngularJS的一个好主意。 首先注入凉亭或npm(以优先为准)
bower install jquery-scrollLock --save
npm install jquery-scroll-lock --save
添加以下指令。我选择将其添加为属性
(function() {
   \'use strict\';

    angular
       .module(\'app\')
       .directive(\'isolateScrolling\', isolateScrolling);

       function isolateScrolling() {
           return {
               restrict: \'A\',
               link: function(sc, elem, attrs) {
                  $(\'.scroll-container\').scrollLock();
               }
           }
       }
})();
插件无法在其网站上记录的重要内容是必须遵循的HTML结构。
<div class=\"scroll-container locked\">
    <div class=\"scrollable\" isolate-scrolling>
         ... whatever ...
    </div>
</div>
属性“ 77”必须包含“ 78”类,并且所有属性都必须位于“ 79”类或您选择的任何类之内,并且“ 80”类必须是级联的。     
值得一提的是,在处理固定位置元素时,使用ReactJS,AngularJS,VueJS等现代框架,可以轻松解决此问题。示例是侧面板或覆盖的元素。 该技术称为\“ Portal \”,这意味着该应用中使用的组件之一(无需从使用位置实际提取它)会将其子项安装在body元素底部,外部您要避免滚动的父级。 请注意,它不会避免滚动body元素本身。您可以结合使用此技术并将应用程序安装在滚动div中以达到预期的效果。 React的material-ui中的示例门户实现:https://material-ui-next.com/api/portal/     
ES 6跨浏览器+移动vanila 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)};
}
    
我正在寻找MooTools,这是第一个出现的。 原始的MooTools示例可以向上滚动,但不能向下滚动,因此我决定编写此示例。 MooTools 1.4.5:http://jsfiddle.net/3MzFJ/ MooTools 1.3.2:http://jsfiddle.net/VhnD4/ MooTools 1.2.6:http://jsfiddle.net/xWrw4/
var stopScroll = function (e) {
    var scrollTo = null;
    if (e.event.type === \'mousewheel\') {
        scrollTo = (e.event.wheelDelta * -1);
    } else if (e.event.type === \'DOMMouseScroll\') {
        scrollTo = 40 * e.event.detail;
    }
    if (scrollTo) {
        e.preventDefault();
        this.scrollTo(0, scrollTo + this.scrollTop);
    }
    return false;
};
用法:
(function)($){
    window.addEvent(\'domready\', function(){
        $$(\'.scrollable\').addEvents({
             \'mousewheel\': stopScroll,
             \'DOMMouseScroll\': stopScroll
        });
    });
})(document.id);
    
使用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();
    }
});
    
您可以这样尝试:
$(\'#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\');
});
    

要回复问题请先登录注册