Pass mousewheel event through fixed content

戏子无情 提交于 2019-12-20 17:38:03

问题


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.


回答1:


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;

}




回答2:


A much, MUCH simpler, but much less widely supported, answer is the following:

#fixed{ pointer-events:none; }

jsFiddle
Doesn't work in IE at all though unfortunately! But you could use modernizr or somesuch to detect whether it was supported and use the jQuery as a stop-gap where it isn't.

Courtesy of Mr. Dominic Stubbs




回答3:


I had this problem and this works for me (using jquery):

$(document).ready( function (){
    $('#fixed').on('mousewheel',function(event) {
        var scroll = $('#container').scrollTop();
        $('#container').scrollTop(scroll - event.originalEvent.wheelDeltaY);
        return true;
    });
});

Works on Safari and Chrome: http://jsfiddle.net/5bwWe/36/




回答4:


UPDATE (August 2016): It seems the browser implementations have changed and it's no longer possible to re-dispatch a WheelEvent on a different target. See the discussion here.

For an alternative solution that should work across platforms, try this:

var target = $('#container').get(0);
$('#fixed').on('wheel', function (e) {
  var o = e.originalEvent;
  target.scrollTop += o.deltaY;
  target.scrollLeft += o.deltaX;
});

Working example: https://gist.run/?id=6a8830cb3b0564e7b16a4f31a9405386


Original answer below:

Actually, the best way to do it is to copy the original event. I've tried @Tuokakouan's code but scrolling behaves strangely (too fast) when we use a multitouch touchpad that has inertia. Here's my code:

var target = $('#container').get(0);

$('#fixed').on('wheel', function(e){
  var newEvent = new WheelEvent(e.originalEvent.type, e.originalEvent);
  target.dispatchEvent(newEvent);
});

You can try it here: http://jsfiddle.net/NIXin/t2expL6u/1/

What I'm trying to do now is also to pass the touch events, without much success. Since mobile phones and touch screens are now more popular, some people might want to scroll using their fingers instead - neither of the answers offered solves that.




回答5:


Well,all solutions with js are kind of delayed when scrolling on it. if the fixed element you use is just for display, then I have a good css tricks to achieve that.

make the fixed element z-index:-1 and the container element background-color:transparent here is the jsfiddle you can see: https://jsfiddle.net/LeeConan/4xz0vcgf/1/



来源:https://stackoverflow.com/questions/7182502/pass-mousewheel-event-through-fixed-content

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!