通过固定内容传递鼠标滚轮事件

时间:2011-08-24 21:27:34

标签: javascript jquery javascript-events mousewheel

理解这一点的最佳方法是查看this fiddle

请注意鼠标滚轮在红色框中的固定内容上的效果如何。我想滚动的可滚动div。

如果小提琴死了 - 基本上我有一个可滚动的div,上面有固定元素。通常,当鼠标滚过可滚动的div时,它当然会滚动。但是如果你超过了固定元素,那么就不会发生滚动。根据您的站点布局,这可能对用户来说是直观的。

jQuery解决方案没问题。

5 个答案:

答案 0 :(得分:11)

一个更简单,更简单但更不广泛支持的答案如下:

#fixed{ pointer-events:none; }

jsFiddle
不幸的是,在IE中根本不起作用!但是你可以使用modernizr或者某些东西来检测它是否被支持,并使用jQuery作为止损而不是。

由Dominic Stubbs先生提供

答案 1 :(得分:8)

我遇到了这个问题,这对我有用(使用jquery):

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

适用于Safari和Chrome:http://jsfiddle.net/5bwWe/36/

答案 2 :(得分:5)

我认为这就是你所要求的!

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

编辑:将jsFiddle链接更新为实际工作的链接 DOUBLE EDIT:最好在进一步测试时免除.animate()... jsFiddle Example

TRIPLE EDIT: 不那么漂亮(并且页面上有很多元素可能会非常慢),but this works而且我欠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;

}

答案 3 :(得分:4)

更新(2016年8月):似乎浏览器实施已经改变,并且不再可能在不同的目标上重新调度WheelEvent。请参阅讨论here

对于应该跨平台工作的替代解决方案,请尝试以下方法:

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

工作示例:https://gist.run/?id=6a8830cb3b0564e7b16a4f31a9405386


以下原始答案:

实际上,最好的方法是复制原始事件。我尝试过@Tuokakouan的代码,但是当我们使用具有惯性的多点触控板时,滚动表现得很奇怪(太快)。 这是我的代码:

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

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

您可以在此处试用:http://jsfiddle.net/NIXin/t2expL6u/1/

我现在要做的也是通过触摸事件,但没有取得多大成功。由于手机和触摸屏现在更受欢迎,有些人可能会想要用手指滚动 - 所提供的答案都没有解决。

答案 4 :(得分:0)

嗯,所有带js的解决方案在滚动时都会有所延迟。如果您使用的固定元素仅用于显示,那么我有一个很好的CSS技巧来实现它。

制作固定元素background-color:transparent和容器元素user 这是你可以看到的jsfiddle:https://jsfiddle.net/LeeConan/4xz0vcgf/1/