Reputation: 3033
The question is so long that coming up with a title that summarises it proved tricky.
So anyway. I have a div
that has overflow: auto
and that frequently does flow over so the scrollbar appears. Then I have a div
that has position: fixed
and is positioned on top of the content div
.
Now when I have a fixed-positioned div
over the html body itself, I can scroll the document with the wheel when I have my mouse over the div
. Not so lucky with the aforementioned div
.
Is there a way to scroll the div
"through" the fixed-positioned one?
I noticed that even catching the scroll event when over the fixed div isn't easy; the event isn't fired unless the fixed div itself is scrollable.
I made a simple jsFiddle here and for your convenience stripped it of all the JavaScript I tried.
Edit: I need to retain other mouse functions with the fixed div so turning pointer-events off isn't the solution in my case.
Upvotes: 18
Views: 17513
Reputation: 21
While the accepted answer definitely will get you the result you need, there is a noticeable difference in the smoothness of scrolling naturally and the scrolling triggered by setting scrollTop.
This utilizes the best parts of pointer-events: none;
without actually removing the ability to interact with your fixed elements.
function enableScroll(e) {
var self = $(this);
self.css('pointer-events', 'none');
clearTimeout(this.timer);
this.timer = setTimeout(function () {
self.css('pointer-events', 'all');
}, 100);
}
$('#fixed').on('mousewheel DOMMouseScroll', enableScroll);
Upvotes: 2
Reputation: 2334
var fixedElement = document.getElementById("fixed");
function fixedScrolled(e) {
var evt = window.event || e;
var delta = evt.detail ? evt.detail * (-120) : evt.wheelDelta; //delta returns +120 when wheel is scrolled up, -120 when scrolled down
$("#content").scrollTop($("#content").scrollTop() - delta);
}
var mousewheelevt = (/Gecko\//i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel";
if (fixedElement.attachEvent)
fixedElement.attachEvent("on" + mousewheelevt, fixedScrolled);
else if (fixedElement.addEventListener)
fixedElement.addEventListener(mousewheelevt, fixedScrolled, false);
jsFiddle Demo - Scroll!
Upvotes: 19
Reputation: 3033
I came up with a more elegant solution, however as it was Ruirize's answer that got me to the right track I gave him the accept tag.
$('#fixed').on('mousewheel DOMMouseScroll', function(event) {
$('#content').scrollTop($('#content').scrollTop() - (event.originalEvent.wheelDelta || -event.originalEvent.detail*30));
});
It is also displayed at jsFiddle.
Upvotes: 12
Reputation: 14575
What you are looking for is pointer-events: none;
This makes the pointer not interact with that div essentially, so just do
#fixed {
pointer-events: none;
}
And you will get your desired outcome with no JS required. This will stop all other interaction with the div though, if you need to interact with it for some reason I'm afraid you'll have to look into a JS solution.
Upvotes: 30