Событие Mousewheel в современных браузерах

Я хотел бы иметь чистый и приятный JavaScript для события колесика мыши, поддерживающий только последнюю версию обычных браузеров без устаревшего кода для устаревших версий, без какой-либо JS-инфраструктуры.

Событие Mousewheel прекрасно объясняется здесь. Как упростить это для текущих последних версий браузеров?

У меня нет доступа ко всем браузерам, чтобы протестировать его, поэтому caniuse.com очень поможет меня. Увы, колесико там не упоминается.

Основываясь на комментарии Дерека, я написал это решение. Это действительно для всех браузеров?

someObject.addEventListener("onwheel" in document ? "wheel" : "mousewheel", function(e) {
  e.wheel = e.deltaY ? -e.deltaY : e.wheelDelta/40;
  // custom code
});

person Jan Turoň    schedule 17.02.2013    source источник
comment
Chrome и IE поддерживают MouseWheelEvent, а Firefox поддерживает _ 2_. Для прослушивания через браузер см. здесь.   -  person Derek 朕會功夫    schedule 18.02.2013
comment
Добавлено к мнению Дерека. В этих случаях вам действительно следует оценить совместимость браузеров. Вы можете сделать это с помощью Modernizr (modernizr.com). Это сделает вашу жизнь намного проще :)   -  person    schedule 18.02.2013
comment
В настоящее время, согласно MDN, поддерживается событие wheel во всех современных настольных браузерах.   -  person gdros    schedule 31.10.2016


Ответы (3)


Чисто и просто:

window.addEventListener("wheel", event => console.info(event.deltaY));

Браузеры могут возвращать разные значения дельты (например, Chrome возвращает +120 (прокрутка вверх) или -120 (прокрутка вниз). Хороший трюк для нормализации - извлечь его знак, эффективно конвертируя его в _4 _ / _ 5_:

window.addEventListener("wheel", event => {
    const delta = Math.sign(event.deltaY);
    console.info(delta);
});

Ссылка: MDN.

person Lucio Paiva    schedule 11.07.2018
comment
Я бы предпочел сохранить абсолютное значение wheelDelta для определения скорости прокрутки. Есть ли какая-нибудь формула для нормализации этого среди браузеров? - person Jan Turoň; 11.07.2018
comment
К сожалению, если вы хотите использовать абсолютное значение, формулы нет. Вам придется полагаться на какую-то таблицу с эмпирически полученными значениями для каждой комбинации браузера / ОС. Для обычных мышей значение wheelDelta всегда фиксировано, независимо от того, насколько быстро вы прокручиваете, поэтому можно делать то, что я предложил выше. Однако, если вы хотите запечатлеть чувствительность трекпада, например (я думаю, это то, что вы ищете), тогда у вас есть своя собственная. Будем надеяться, что в будущем это значение будет стандартизировано для всех браузеров. - person Lucio Paiva; 11.07.2018
comment
При этом в консоли появляется предупреждение: [Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. Consider marking event handler as 'passive' to make the page more responsive. See chromestatus.com/feature/5745543795965952 - person Derk Jan Speelman; 09.09.2018
comment
Интересно. Я использую Chrome 68 и не вижу этого предупреждения. @DerkJanSpeelman Вы уверены, что тестируете тот же код, что и выше? Я просто попробовал обе версии (с извлечением дельта-знака и без него), но не смог воспроизвести то, что вы видите. - person Lucio Paiva; 09.09.2018
comment
@LucioPaiva Я действительно использовал более старую версию. Но после обновления я все еще вижу такое же предупреждение. Вот мой код: window.onwheel = () => { let delta = Math.sign(event.wheelDelta); console.log(delta) }. Я также вижу такое же предупреждение, когда просто копирую пример кода в этом ответе. - person Derk Jan Speelman; 09.09.2018
comment
Я все еще не могу воспроизвести это здесь. Может разные операционные системы? Пробую на Ubuntu 18.04. Кроме того, запускаете ли вы одновременно какой-либо дополнительный код? В любом случае, MDN упоминает, что передача третьего параметра { passive: true } to addEventListener() решает проблему, если вам не нужно event.preventDefault(). Если да, то похоже, что мало что можно сделать (проверьте людей, которые жалуются в комментариях). - person Lucio Paiva; 09.09.2018
comment
у меня нет event.delta, это null, почему? - person datdinhquoc; 18.07.2019
comment
@datdinhquoc многие вещи могут быть неправильными. Вам следует опубликовать новый вопрос с указанием вашего браузера и показом некоторого кода, чтобы другие могли помочь. - person Lucio Paiva; 18.07.2019
comment
@LucioPaiva мне пришлось использовать event.originalEvent.deltaY - person datdinhquoc; 19.07.2019
comment
Используйте deltaMode. Это единственный способ обеспечить совместимость прокрутки. - person karlcow; 02.06.2020

Вот статья, которая описывает это и дает пример:

http://www.sitepoint.com/html5-javascript-mouse-wheel/

Соответствующий код за вычетом конкретного примера изменения размера изображения:

var myitem = document.getElementById("myItem");
if (myitem.addEventListener)
{
    // IE9, Chrome, Safari, Opera
    myitem.addEventListener("mousewheel", MouseWheelHandler, false);
    // Firefox
    myitem.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
}
// IE 6/7/8
else
{
    myitem.attachEvent("onmousewheel", MouseWheelHandler);
}

function MouseWheelHandler(e)
{
    // cross-browser wheel delta
    var e = window.event || e; // old IE support
    var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));

    return false;
}
person Almo    schedule 26.09.2014
comment
Отличный ответ. Требует большего внимания. Множество неполных ответов по этому вопросу, - person Terrance00; 07.02.2017
comment
Это устаревшее событие, которое было удалено из многих браузеров. Сейчас нужно использовать событие WheelEvent (developer.mozilla.org/en -US / docs / Web / API / WheelEvent) - person dug; 28.12.2019
comment
Это полезно для поддержки старых браузеров, в частности IE не поддерживает Math.sign вообще, но Math.max и Math.min поддерживаются. caniuse.com/?search=Math.sign - person ryancdotnet; 08.09.2020

Это также будет работать в Firefox, Chrome и Edge:

window.addEventListener("wheel", function(e) {
    var dir = Math.sign(e.deltaY);
    console.log(dir);
});
person Iter Ator    schedule 03.01.2019