Получить события колесика мыши в jQuery?

Есть ли способ получить события колесика мыши (не говоря уже о событиях scroll) в jQuery?


person thejh    schedule 18.11.2011    source источник
comment
Быстрый поиск показал, что этот плагин может помочь.   -  person Jerad Rose    schedule 19.11.2011
comment
Это решение работает для меня: stackoverflow.com/questions/7154967/jquery-detect-scrolldown   -  person Albert Gan    schedule 06.03.2014
comment
@thejh опубликовал новый ответ по этому поводу с событиями DOM3: stackoverflow.com/a/24707712/2256325   -  person Sergio    schedule 14.07.2014
comment
Возможный дубликат jQuery scroll () обнаруживает, когда пользователь прекращает прокрутку   -  person divy3993    schedule 02.02.2017
comment
Просто примечание об этом. Если вы просто хотите обнаружить изменения во входных данных, а они не обнаруживают изменения с помощью колесика мыши, попробуйте $(el).on('input', ...   -  person rybo111    schedule 24.06.2018


Ответы (15)


Существует плагин, который определяет перемещение колесика мыши вверх / вниз и скорость в регионе.

person Darin Dimitrov    schedule 18.11.2011
comment
плагин? давай .. проверьте ответ ниже, вы можете обойтись без - person ; 13.10.2013

Привязка как к mousewheel, так и к DOMMouseScroll мне очень понравилась:

$(window).bind('mousewheel DOMMouseScroll', function(event){
    if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
        // scroll up
    }
    else {
        // scroll down
    }
});

Этот метод работает в IE9 +, Chrome 33 и Firefox 27.


Изменить - март 2016 г.

Я решил вернуться к этому вопросу, так как это было давно. Страница MDN для события прокрутки имеет отличный способ получить позицию прокрутки, в которой используется requestAnimationFrame, что очень предпочтительнее, чем мой предыдущий метод обнаружения. Я изменил их код, чтобы обеспечить лучшую совместимость в дополнение к направлению и положению прокрутки:

(function() {
  var supportOffset = window.pageYOffset !== undefined,
    lastKnownPos = 0,
    ticking = false,
    scrollDir,
    currYPos;

  function doSomething(scrollPos, scrollDir) {
    // Your code goes here...
    console.log('scroll pos: ' + scrollPos + ' | scroll dir: ' + scrollDir);
  }

  window.addEventListener('wheel', function(e) {
    currYPos = supportOffset ? window.pageYOffset : document.body.scrollTop;
    scrollDir = lastKnownPos > currYPos ? 'up' : 'down';
    lastKnownPos = currYPos;

    if (!ticking) {
      window.requestAnimationFrame(function() {
        doSomething(lastKnownPos, scrollDir);
        ticking = false;
      });
    }
    ticking = true;
  });
})();

See the Pen Vanilla JS Scroll Tracking by Jesse Dupuy (@blindside85) on CodePen.

Этот код в настоящее время работает в Chrome v50, Firefox v44, Safari v9, and IE9+

Использованная литература:

person Jesse Dupuy    schedule 19.03.2014
comment
Это сработало для меня лучше всего. Однако этот сценарий запускается при щелчке колеса прокрутки. Для некоторых скриптов это может быть непосильно. Есть ли способ обрабатывать каждое событие прокрутки как один экземпляр, а не запускать скрипт для каждого щелчка колеса прокрутки? - person invot; 28.05.2014
comment
Не особо. Из того, что я видел, многие люди либо избегают иметь дело с отслеживанием прокрутки, либо вместо этого будут использовать таймер (например, проверять положение пользователя на странице каждые x миллисекунд и т. Д.). Если есть более производительное решение, я определенно хочу об этом знать! - person Jesse Dupuy; 08.08.2014
comment
Я нашел способ сделать это: stackoverflow.com/questions/23919035/ - person invot; 08.08.2014
comment
@JesseDupuy, если нужно использовать таймер, убедитесь, что вы (или кто-либо когда-либо это читает) использует систему очередей для ваших различных потоков. Объединение таймеров ужасно влияет на рендеринг. Я создал сценарий для этого случая, которым делюсь на github: github.com/erik-landvall/animator - person superhero; 19.08.2015
comment
Обновил мой ответ современной информацией + ссылка Codepen :) - person Jesse Dupuy; 07.03.2016
comment
Как мы можем отменить дважды колесико мыши? - person ShibinRagh; 23.03.2016
comment
Вы говорите, что событие теперь запускается дважды, используя мой старый / новый код? Пытаюсь убедиться, что понимаю вопрос. - person Jesse Dupuy; 23.03.2016
comment
Спасибо за обновления. Можете ли вы скопировать свой код в свой ответ? Никогда не знаешь, выйдет ли когда-нибудь кодовый ключ из строя. Это уже случалось раньше. - person JDB still remembers Monica; 23.04.2016
comment
@JesseDupuy, я бы поддержал этот ответ, но ваша обновленная версия не работает, если документ соответствует представлению (ширина: 100vh; высота: 100vh) или имеет переполнение: hidden ;. window.addEventListener ('scroll', обратный вызов) не является правильным ответом на window.addEventListener ('mousewheel', обратный вызов). - person Daniel; 06.05.2016
comment
Отличный ответ. Как отметил @Daniel, overflow: hidden не работает с новой версией, но исходная отлично работает с ней. Мне он нужен для веб-приложения, которое использует прокрутку мыши для увеличения, и оно отлично работает. - person kevinmicke; 16.02.2017

На данный момент в 2017 году вы можете просто написать

$(window).on('wheel', function(event){

  // deltaY obviously records vertical scroll, deltaX and deltaZ exist too.
  // this condition makes sure it's vertical scrolling that happened
  if(event.originalEvent.deltaY !== 0){

    if(event.originalEvent.deltaY < 0){
      // wheeled up
    }
    else {
      // wheeled down
    }
  }
});

Работает с текущими версиями Firefox 51, Chrome 56, IE9 +

person Louis Ameline    schedule 05.02.2017
comment
Этот ответ работает лучше, чем все остальные! - person VDWWD; 15.04.2021
comment
event.originalEvent.deltaY может быть 0 при горизонтальной прокрутке (только что попробовал на моем ноутбуке), так что вы, вероятно, захотите, если x<0 иначе, если x>0. - person ajax333221; 29.05.2021

Ответы о событии «колесико мыши» относятся к устаревшему событию. Стандартное мероприятие - это просто «колесо». См. https://developer.mozilla.org/en-US/docs/Web/Reference/Events/wheel

person Brian Di Palma    schedule 12.08.2013
comment
Я попробовал их и обнаружил: wheel работает в Firefox и IE, но не в Chrome. колесо мыши работает в Chrome и IE, но не в Firefox. DOMMouseScroll работает только в Firefox. - person Curtis Yallop; 23.08.2013
comment
Ого, это сэкономило мне много времени. Спасибо! - person gustavohenke; 20.11.2013
comment
Похоже, в августе 2013 года Chrome добавил поддержку колеса: code.google. ru / p / chromium / issues / detail? id = 227454 - person rstackhouse; 07.07.2014
comment
Safari по-прежнему не поддерживает событие колеса. - person Thayne; 11.09.2014
comment
Как сказано в вашей документации, событие wheel поддерживается Edge, а не IE, что не одно и то же. CanIuse - person Alex; 06.03.2018

Это сработало для меня :)

 //Firefox
 $('#elem').bind('DOMMouseScroll', function(e){
     if(e.originalEvent.detail > 0) {
         //scroll down
         console.log('Down');
     }else {
         //scroll up
         console.log('Up');
     }

     //prevent page fom scrolling
     return false;
 });

 //IE, Opera, Safari
 $('#elem').bind('mousewheel', function(e){
     if(e.originalEvent.wheelDelta < 0) {
         //scroll down
         console.log('Down');
     }else {
         //scroll up
         console.log('Up');
     }

     //prevent page fom scrolling
     return false;
 });

из stackoverflow

person Anjith K P    schedule 24.09.2013

Вот и ванильный раствор. Может использоваться в jQuery, если в функцию передано событие event.originalEvent, которое jQuery делает доступным как свойство события jQuery. Или, если внутри функции callback мы добавляем перед первой строкой: event = event.originalEvent;.

Этот код нормализует скорость / величину колеса и положителен для прокрутки вперед в типичной мыши и отрицателен при движении колеса мыши назад.

Демо: http://jsfiddle.net/BXhzD/

var wheel = document.getElementById('wheel');

function report(ammout) {
    wheel.innerHTML = 'wheel ammout: ' + ammout;
}

function callback(event) {
    var normalized;
    if (event.wheelDelta) {
        normalized = (event.wheelDelta % 120 - 0) == -0 ? event.wheelDelta / 120 : event.wheelDelta / 12;
    } else {
        var rawAmmount = event.deltaY ? event.deltaY : event.detail;
        normalized = -(rawAmmount % 3 ? rawAmmount * 10 : rawAmmount / 3);
    }
    report(normalized);
}

var event = 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll';
window.addEventListener(event, callback);

Существует также плагин для jQuery, который более подробен в коде и немного лишний: https://github.com/brandonaaron/jquery-mousewheel.

person Sergio    schedule 11.07.2014

Это работает во всех последних версиях IE, Firefox и Chrome.

$(document).ready(function(){
        $('#whole').bind('DOMMouseScroll mousewheel', function(e){
            if(e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0) {
                alert("up");
            }
            else{
                alert("down");
            }
        });
    });
person futuredayv    schedule 09.09.2015

Сегодня я застрял в этой проблеме и обнаружил, что этот код у меня работает нормально

$('#content').on('mousewheel', function(event) {
    //console.log(event.deltaX, event.deltaY, event.deltaFactor);
    if(event.deltaY > 0) {
      console.log('scroll up');
    } else {
      console.log('scroll down');
    }
});
person Prafull Sharma    schedule 03.06.2016

используйте этот код

 knob.bind('mousewheel', function(e){  
 if(e.originalEvent.wheelDelta < 0) {
    moveKnob('down');
  } else {
    moveKnob('up');
 }
  return false;
});
person Bal mukund kumar    schedule 26.04.2017

Плагин, опубликованный @DarinDimitrov, jquery-mousewheel, не работает с jQuery 3+. Было бы более целесообразно использовать jquery-wheel, который работает с jQuery 3+.

Если вы не хотите идти по маршруту jQuery, настоятельно рекомендуется использовать mousewheel событие, поскольку оно нестандартно и не поддерживается во многих местах. Вместо этого в нем говорится, что вам следует использовать событие wheel в качестве получите гораздо больше конкретики в отношении того, что именно означают получаемые вами значения. Он поддерживается большинством основных браузеров.

person Coburn    schedule 03.11.2016

моя комбинация выглядит так. он исчезает и исчезает при каждой прокрутке вниз / вверх. в противном случае вам придется прокручивать до заголовка, чтобы его можно было скрыть.

var header = $("#header");
$('#content-container').bind('mousewheel', function(e){
    if(e.originalEvent.wheelDelta > 0) {
        if (header.data('faded')) {
            header.data('faded', 0).stop(true).fadeTo(800, 1);
        }
    }
    else{
        if (!header.data('faded')) header.data('faded', 1).stop(true).fadeTo(800, 0);
    }
});

приведенный выше не оптимизирован для сенсорного / мобильного устройства, я думаю, что он лучше подходит для всех мобильных устройств:

var iScrollPos = 0;
var header = $("#header");
$('#content-container').scroll(function () {

    var iCurScrollPos = $(this).scrollTop();
    if (iCurScrollPos > iScrollPos) {
        if (!header.data('faded')) header.data('faded', 1).stop(true).fadeTo(800, 0);

    } else {
        //Scrolling Up
        if (header.data('faded')) {
            header.data('faded', 0).stop(true).fadeTo(800, 1);
        }
    }
    iScrollPos = iCurScrollPos;

});
person Thomas Hartmann    schedule 18.06.2014

Если вы используете упомянутый плагин jquery mousewheel, то как насчет использования второго аргумента функции обработчика событий - delta:

$('#my-element').on('mousewheel', function(event, delta) {
    if(delta > 0) {
    console.log('scroll up');
    } 
    else {
    console.log('scroll down');
    }
});
person Mojo    schedule 18.04.2017

Я думаю, что многие ключевые вещи разбросаны повсюду, и мне нужно было прочитать все ответы, чтобы мой код работал так, как я хотел, поэтому я опубликую свои выводы только в одном месте:

  • Вы должны использовать событие "wheel" вместо других устаревших или специфичных для браузера событий.
  • Многие люди здесь ошибаются: противоположность x>0 - x<=0, а противоположность x<0 - x>=0, многие из приведенных здесь ответов будут запускать прокрутку вниз или вверх неправильно, когда x=0 (горизонтальная прокрутка).
  • Кто-то спрашивал, как добавить к нему чувствительность, для этого вы можете использовать setTimeout() с задержкой примерно 50 мс, которая меняет какой-то вспомогательный флаг isWaiting=false, и вы защищаете себя с помощью if(isWaiting), а затем ничего не делаете. Когда он срабатывает, вы вручную изменяете isWaiting=true, а чуть ниже этой строки вы снова запускаете setTimeout, который позже изменит isWaiting=false через 50 мс.
person ajax333221    schedule 29.05.2021

Недавно у меня возникла такая же проблема, когда $(window).mousewheel возвращался undefined

Я сделал $(window).on('mousewheel', function() {});

В дальнейшем для его обработки я использую:

function (event) {
    var direction = null,
        key;

    if (event.type === 'mousewheel') {
        if (yourFunctionForGetMouseWheelDirection(event) > 0) {
            direction = 'up';
        } else {
            direction = 'down';
        }
    }
}
person Szymon Toda    schedule 24.04.2014
comment
Вы не сказали, что есть newUtilities.getMouseWheelDirection - person ccsakuweb; 29.06.2014
comment
Это выходит за рамки этого вопроса. Так что это не сайт для копирования и вставки. - person Szymon Toda; 01.07.2014

person    schedule
comment
Событие DOMMouseScroll используется в FF, поэтому вам нужно прослушивать оба .bind('DOMMouseScroll mousewheel') { evetns developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/ - person mrzmyr; 07.04.2013
comment
e.originalEvent.wheelDelta не определен в FF23 - person hofnarwillie; 10.09.2013
comment
Вам не нужно делить на 120, это бесполезная трата процессора - person venimus; 30.09.2013
comment
должно быть, это был лучший ответ - person ; 13.10.2013
comment
Но в любом случае, зачем вам делить его на 120? Что это за константа? (Не обязательно, как указал Венимус.) - person mshthn; 04.10.2015
comment
Спасибо, махди шахбази! Это мне очень помогло. - person Bondsmith; 27.02.2017
comment
Я бы рекомендовал использовать второй аргумент функции обработчика событий - delta: $('#el').on('mousewheel', function(e, delta) { if(delta > 0) { /*up*/ } else { /*down*/ }}). См. этот ответ. - person Mojo; 18.04.2017
comment
@Mojo, когда я использовал delta, он дает undefined с версией Chrome 59.0.3071.115 (официальная сборка) (64-разрядная версия) - person Elshan; 29.06.2017
comment
Событие mousewheel нестандартно и также устарело. Вместо этого используйте WheelEvent. - person GetFree; 15.03.2018
comment
Это действительно работает, но проблема в том, что если вы прокручиваете сенсорную панель, это создает много прокруток, то есть для прокрутки с сенсорной панелью с высокой скоростью прокручиваются несколько экранов. В решении всех подобных проблем очень помог этот плагин: github.com/Promo/wheel-indicator - person Yesha; 11.04.2019