mrtsherman mrtsherman - 4 months ago 21
jQuery Question

Pass mousewheel event through fixed content

The best way to understand this is to look at this fiddle.

Notice how mouse wheel over the fixed content in the red box does nothing. I would like the scrollable div to scroll.

In case the fiddle dies - basically I have a scrollable div with a fixed element over it. Typically when you mouse wheel over a scrollable div it will of course scroll. But if you are over the fixed element instead then no scroll happens. Depending on your site layout this could be counter intuitive to a user.

jQuery solutions are okay.

Answer

I think this does what you're asking for!

$('#fixed').bind('mousewheel', function(e){
     var scrollTo= (e.wheelDelta*-1) + $('#container').scrollTop();
    $("#container").scrollTop(scrollTo);
});

EDIT: Updated the jsFiddle link to one that actually works
DOUBLE EDIT: Best to dispense with the .animate() on further testing...
jsFiddle Example

TRIPLE EDIT: Much less pretty (and will probably be horribly slow with a lot of elements on the page), but this works and I owe a lot to this stackoverflow answer.

$('#fixed').bind('mousewheel', function(e) {


var potentialScrollElements = findIntersectors($('#fixed'), $('*:not(#fixed,body,html)'));
$.each(potentialScrollElements, function(index, Element) {
    var hasVerticalScrollbar = $(Element)[0].scrollHeight > $(Element)[0].clientHeight;
    if (hasVerticalScrollbar) {
        var scrollTo = (e.wheelDelta * -1) + $(Element).scrollTop();
        $(Element).scrollTop(scrollTo);
    }
});
});


function findIntersectors(targetSelector, intersectorsSelector) {
var intersectors = [];

var $target = $(targetSelector);
var tAxis = $target.offset();
var t_x = [tAxis.left, tAxis.left + $target.outerWidth()];
var t_y = [tAxis.top, tAxis.top + $target.outerHeight()];

$(intersectorsSelector).each(function() {
    var $this = $(this);
    var thisPos = $this.offset();
    var i_x = [thisPos.left, thisPos.left + $this.outerWidth()]
    var i_y = [thisPos.top, thisPos.top + $this.outerHeight()];

    if (t_x[0] < i_x[1] && t_x[1] > i_x[0] && t_y[0] < i_y[1] && t_y[1] > i_y[0]) {
        intersectors.push($this);
    }

});
return intersectors;

}