I have a little "floating tool box" - a div with position:fixed; overflow:auto
.
Works just fine.
But when scrolling inside that box (with the mouse wheel) and reaching the bottom OR top, the parent element "takes over" the "scroll request" : The document behind the tool box scrolls.
- Which is annoying and not what the user "asked for".
I'm using jQuery and thought I could stop this behaviour with event.stoppropagation():
$("#toolBox").scroll( function(event){ event.stoppropagation() });
It does enter the function, but still, propagation happens anyway (the document scrolls)
- It's surprisingly hard to search for this topic on SO (and Google), so I have to ask:
How to prevent propagation / bubbling of the scroll-event ?
Edit:
Working solution thanks to amustill (and Brandon Aaron for the mousewheel-plugin here:
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();
}
}
});
I hate necro posting but I was searching for this for MooTools and this was the first that came up. The original MooTools example would work with scrolling up, but not scrolling down so I decided to write this one.
Usage:
I am adding this answer for completeness because the accepted answer by @amustill does not correctly solve the problem in Internet Explorer. Please see the comments in my original post for details. In addition, this solution does not require any plugins - only jQuery.
In essence, the code works by handling the
mousewheel
event. Each such event contains awheelDelta
equal to the number ofpx
which it is going to move the scrollable area to. If this value is>0
, then we are scrollingup
. If thewheelDelta
is<0
then we are scrollingdown
.FireFox: FireFox uses
DOMMouseScroll
as the event, and populatesoriginalEvent.detail
, whose+/-
is reversed from what is described above. It generally returns intervals of3
, while other browsers return scrolling in intervals of120
(at least on my machine). To correct, we simply detect it and multiply by-40
to normalize.@amustill's answer works by canceling the event if the
<div>
's scrollable area is already either at the top or the bottom maximum position. However, Internet Explorer disregards the canceled event in situations where thedelta
is larger than the remaining scrollable space.In other words, if you have a
200px
tall<div>
containing500px
of scrollable content, and the currentscrollTop
is400
, amousewheel
event which tells the browser to scroll120px
further will result in both the<div>
and the<body>
scrolling, because400
+120
>500
.So - to solve the problem, we have to do something slightly different, as shown below:
The requisite
jQuery
code is:In essence, this code cancels any scrolling event which would create the unwanted edge condition, then uses jQuery to set the
scrollTop
of the<div>
to either the maximum or minimum value, depending on which direction themousewheel
event was requesting.Because the event is canceled entirely in either case, it never propagates to the
body
at all, and therefore solves the issue in IE, as well as all of the other browsers.I have also put up a working example on jsFiddle.
New web dev here. This worked like a charm for me on both IE and Chrome.
Don't let the number of lines fool you, it is quite simple - just a bit verbose for readability (self documenting code ftw right?)
Also I should mention that the language here is TypeScript, but as always, it is straightforward to convert it to JS.
Don't use
overflow: hidden;
onbody
. It automatically scrolls everything to the top. There's no need for JavaScript either. Make use ofoverflow: auto;
:HTML Structure
Styling
Play with the demo here.
This actually works in AngularJS. Tested on Chrome and Firefox.
jQuery plugin with emulate natural scrolling for Internet Explorer
https://github.com/basselin/jquery-mousewheel-stop-propagation/blob/master/mousewheelStopPropagation.js