【问题标题】:Pass mousewheel event through fixed content通过固定内容传递鼠标滚轮事件
【发布时间】:2011-11-03 04:39:28
【问题描述】:

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

请注意,鼠标滚轮在红色框中的固定内容上没有任何作用。我想让可滚动的 div 滚动。

万一小提琴死了 - 基本上我有一个可滚动的 div,上面有一个固定的元素。通常,当您将鼠标滚轮悬停在可滚动的 div 上时,它当然会滚动。但是,如果您在固定元素上方,则不会发生滚动。根据您的网站布局,这可能对用户来说是反直觉的。

jQuery 解决方案还可以。

【问题讨论】:

  • 请修改问题以提供有关您想要完成的任务的更多详细信息。 (例如,当您在固定内容上使用鼠标滚轮时,我假设您期望具有高内容的 div 滚动,但如果您在问题中这么说会有所帮助。)
  • 是的。这就是我的意思。因为这是屏幕上唯一的可滚动对象,所以我认为这很明显。
  • 我认为回答您的问题是相当明显的;对于可能从中受益的未来 StackOverflow 用户而言,情况就不那么好了。
  • 这是有道理的。特别是如果我的小提琴最终消失了。我将我的问题更新为明确的。

标签: javascript jquery dom-events mousewheel


【解决方案1】:

一个简单得多,但得到广泛支持的答案如下:

#fixed{ pointer-events:none; }

jsFiddle
不幸的是,在 IE 中根本不起作用!但是你可以使用 modernizr 或类似的东西来检测它是否受支持,并在不支持的地方使用 jQuery 作为权宜之计。

感谢 Dominic Stubbs 先生

【讨论】:

  • +1 这是一个很好的建议 Touk。太糟糕了,我将不得不等待十年才能成为 IE 的标准并且每个人都已迁移。
  • 但这也会禁用点击,比如固定元素是滚动到顶部的按钮
  • 如果你想像我在我的情况下那样垂直和水平滚动,这似乎是唯一的解决方案
  • 仅供参考,有用于 IE 的 pointer-events: none polyfills。这是一个:github.com/kmewhort/pointer_events_polyfill
【解决方案2】:

我遇到了这个问题,这对我有用(使用 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/

【讨论】:

  • 这太棒了!太感谢了。仅供参考,您也可以通过绑定到 DOMMouseScroll 事件并捕获 event.originalEvent.detail 的值来使其在 Firefox 中工作 - 请参见此处:stackoverflow.com/questions/8886281/…
【解决方案3】:

我认为这可以满足您的要求!

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

编辑:将 jsFiddle 链接更新为实际可用的链接
双重编辑:最好在进一步测试时放弃 .animate()...
jsFiddle Example

三重编辑: but this worksthis 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;

}

【讨论】:

  • 这看起来很有希望。您是否认为有一种方法无需明确知道其下方是什么元素。
  • 请注意,这在 FF 中不起作用。 FF 显然喜欢具有不同属性的DOMMouseWheel 事件。所以采取 Touk 的答案,也将它绑定到dommousewheel。见链接。 help.dottoro.com/ljqeknfl.php
  • 我需要将 e.wheelDelta 更改为 e.originalEvent.wheelDelta 才能正常工作
【解决方案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/

我现在要做的也是传递触摸事件,但没有取得多大成功。由于手机和触摸屏现在更流行,有些人可能想用手指滚动 - 所提供的答案都不能解决这个问题。

【讨论】:

  • 您的解决方案实际上更正了滚动过快的问题。也许一个干净的方法是检测事件是来自触摸板还是鼠标......
  • 我试过小提琴,但当前版本的 Chrome、FireFox 和 IE 都不能工作。
  • @DylanYi 我已经更新了我的答案以反映网络的当前状态。
  • 完美运行!谢谢!顺便说一句,如果它是应该滚动的正文,只需使用var target = $('body').get(0);
【解决方案5】:

好吧,所有带有 js 的解决方案在滚动时都有点延迟。如果您使用的固定元素只是为了显示,那么我有一个很好的 css 技巧来实现这一点。

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

【讨论】:

  • 这使得固定元素下面的任何内容都在它上面
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多