我有一个小的“浮动工具箱”-一个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();
}
}
});
我也遇到过类似的情况,我是这样解决的:
所有可滚动的元素使类可滚动。
$(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,output
在这个线程中给出的所有解决方案都没有提到一个现有的和本地的方法来解决这个问题,而不需要重新排序DOM和/或使用事件阻止技巧。但是有一个很好的理由:这种方法是专有的-并且只能在MS web平台上使用。引用MSDN:
-ms-scroll- chainingproperty -指定当用户在操作过程中达到滚动限制时发生的滚动行为。属性值:
chained -初始值。当用户在操作期间达到滚动限制时,最近的可滚动父元素开始滚动。没有反弹效果显示。
none -当用户在操作过程中碰到滚动限制时,会显示一个反弹效果。
当然,此属性仅在IE10+/Edge上支持。不过,这里有一句很有说服力的话:
为了让您了解防止滚动链接的流行程度,
根据我的快速http档案搜索“-ms-scroll-chaining:无”
在前300K页的0.4%中使用,尽管在
功能,只支持IE/Edge。
现在有好消息了,各位!从Chrome 63开始,我们终于有了针对基于blink的平台的原生疗法——这就是Chrome(显然)和Android WebView(很快)。
引用介绍文章:
The overscroll-behavior property is a new CSS feature that controls
the behavior of what happens when you over-scroll a container
(including the page itself). You can use it to cancel scroll chaining,
disable/customize the pull-to-refresh action, disable rubberbanding
effects on iOS (when Safari implements overscroll-behavior), and more.[...]
The property takes three possible values:
auto - Default. Scrolls that originate on the element may propagate to
ancestor elements.
contain - prevents scroll chaining. Scrolls do not
propagate to ancestors but local effects within the node are shown.
For example, the overscroll glow effect on Android or the
rubberbanding effect on iOS which notifies the user when they've hit a
scroll boundary. Note: using overscroll-behavior: contain on the html
element prevents overscroll navigation actions.
none - same as contain but it also prevents overscroll effects within the node itself (e.g. Android overscroll glow or iOS rubberbanding).
[...] The best part is that using overscroll-behavior does not adversely
affect page performance like the hacks mentioned in the intro!
下面是这个功能的实际情况。这里是相应的CSS模块文档。
更新:Firefox从59版开始加入这个俱乐部,MS Edge预计将在18版实现这个功能。这是相应的犬科用法。
更新2:现在(2022年10月)Safari正式加入了这个俱乐部:从16.0版本开始,overscroll行为不再落后于功能标志。
我在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);
看看Leland Kwong的代码。
基本思路是将wheeleling事件绑定到子元素上,然后使用子元素的原生javascript属性scrollHeight和jquery属性outerHeight来检测滚动的结束,在此基础上返回false以阻止任何滚动。
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;
}
});