事件对象的wheelDelta属性返回undefined。

43

我试图在我的页面上打开灯箱时禁用滚动条,并找到了这个非常有用的脚本,可以完美实现此功能。(http://jsfiddle.net/mrtsherman/eXQf3/3/) 不幸的是,当我将其用于自己的页面时,它也禁用了灯箱中的滚动条。 我开始使用警报来调试代码,只发现事件.wheelDelta在我的页面上返回"未定义",而在JSFiddle中返回-120。


我曾经遇到过类似的问题,最终发现是由于DOM命名空间引起的。你能否展示一些代码,或者再次检查你的名称和ID,也许答案就在那里。 - SpYk3HH
5个回答

62

在jQuery事件处理程序中,event对象并不反映真实事件。 wheelDelta是一个非标准的事件属性IE和Opera,可以通过jQuery事件的originalEvent属性获取。

在jQuery 1.7+中,detail属性不可用于jQuery事件对象。因此,在DOMMouseScroll事件中,您还应该使用 event.originalEvent.detail 来获取此属性。此方法与旧版本的jQuery向后兼容。

event.originalEvent.wheelDelta

演示:http://jsfiddle.net/eXQf3/22/
参考文献:http://api.jquery.com/category/events/event-object/


3
你真是个天才!我看过很多其他的解决方案,但你的代码片段是唯一一个深入核心并且真正可行的! - user1382306
谢谢,你节省了很多时间。 - suvajit

13
$.fn.wheel = function (callback) {
    return this.each(function () {
        $(this).on('mousewheel DOMMouseScroll', function (e) {
            e.delta = null;
            if (e.originalEvent) {
                if (e.originalEvent.wheelDelta) e.delta = e.originalEvent.wheelDelta / -40;
                if (e.originalEvent.deltaY) e.delta = e.originalEvent.deltaY;
                if (e.originalEvent.detail) e.delta = e.originalEvent.detail;
            }

            if (typeof callback == 'function') {
                callback.call(this, e);
            }
        });
    });
};

并像这样使用:

$('body').wheel(function (e) {
    e.preventDefault();
    $('#myDiv').append($('<div>').text(e.delta));
});

非常感谢 @Mark 对该函数进行 jQuery 化 (:


1
最新版的Firefox无法正常工作。在这里找到了隐藏的差异:if(e.originalEvent && e.originalEvent.deltaY) return e.originalEvent.deltaY * -40 - mpen
@Mark已经修复了,现在应该可以工作了。我希望有一种类似于jQuery的通用增量方法,我讨厌这种跨浏览器的问题。 - psycho brm
1
是的,我不确定为什么这不在jQuery核心中。我将其制作成了一个函数:http://jsfiddle.net/mnbayazit/uTbGp/3/ 在FF和Chrome中工作,但还没有让它在IE8中工作。 - mpen
好的,你介意我用你的wheel函数替换我的答案中的代码吗?它更加优雅。或者你可以直接编辑我的答案。 - psycho brm

5
$(this).on('mousewheel DOMMouseScroll', function(e){

  var dat = $(e.delegateTarget).data(); //in case you have set some, read it here.
  var datx = dat.x || 0; // just to show how to get specific out of jq-data object

  var eo = e.originalEvent;
  var xy = eo.wheelDelta || -eo.detail; //shortest possible code
  var x = eo.wheelDeltaX || (eo.axis==1?xy:0);
  var y = eo.wheelDeltaY || (eo.axis==2?xy:0); // () necessary!
  console.log(x,y);

});

可在WebKit和FF中使用,无法在此证明IE :(


3
当我需要WheelDelta时,我将事件传递给这个小宝石...
function getWheelDelta(event) {
    return event.wheelDelta || -event.detail || event.originalEvent.wheelDelta || -event.originalEvent.detail || -(event.originalEvent.deltaY * 25) || null;
}

以下是我使用jQuery获取带有overflow:hidden CSS规则的滚动元素的差异的示例...

$('#parent-id').on('wheel mousewheel DOMMouseScroll', function(event) {
    var node = $('#child-id');
    node.prop('scrollTop', parseFloat(node.prop('scrollTop')) - (getWheelDelta(event) / 2));
    return false;
});

注意:通过添加delta而不是像上面的示例那样减去来反转滚动方向。

注意到有人说类似的事件在FF中不起作用。我在我的代码中也确认了这一点。一旦我有一个确认的解决方案,就会立即更新getWheelDelta - Mavelo
更新以包括Firefox的event.originalEvent.deltaY。由于每个滚轮事件都注册了1+/-,因此乘以25倍的速度。 - Mavelo

2
我已经尝试了您的解决方案,psycho brm,并更改了函数extractDelta(e),使其在Firefox中工作。我使用了e.originalEvent.detail而不是e.detail,因为Firefox返回未定义的delta。我已将解决方案和我的测试代码上传到此帖子。希望能有所帮助。
function extractDelta(e) {
    if (e.wheelDelta) {
        return e.wheelDelta;
    }

    if (e.originalEvent.detail) {
        return e.originalEvent.detail * -40;
    }

    if (e.originalEvent && e.originalEvent.wheelDelta) {
        return e.originalEvent.wheelDelta;
    }
}

“detail”在最新版的Firefox中似乎不存在。现在它似乎被分成了deltaX、Y和Z。 - mpen
1
嗨,马克。我刚在Mac上的Firefox 27.0.1中测试了这段代码,并检查了鼠标滚轮返回的事件。它仍然包含“originalEvent”元素,在其中,您可以找到“detail”元素。我一直在检查它的值,它仍然有效。如果您向后和向前移动滚轮,它会改变其符号,并且根据滚轮的速度而改变其值。我已经获得了正常的值:1、-1、2、-1、-4、1...我不知道您在哪里发现了问题。 - Timbergus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接