我有一个小的“浮动工具箱”-一个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();
}
}
});
值得一提的是,在像reactJS, AngularJS, VueJS等现代框架中,当处理固定位置元素时,这个问题有简单的解决方案。例如侧板或叠加元素。
这种技术被称为“传送门”,这意味着应用程序中使用的一个组件,不需要从你正在使用它的地方实际提取它,将在body元素的底部装载它的子元素,在你试图避免滚动的父元素之外。
注意,它不会避免滚动body元素本身。你可以结合这种技术,在滚动div中安装你的应用程序,以达到预期的结果。
React material-ui中的门户实现示例:https://material-ui-next.com/api/portal/
我在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);
编辑:代码依赖的例子
对于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的平滑滚动就会打败这个黑客。