Otrzymujesz zdarzenia kółka myszy w jQuery?


134

Czy istnieje sposób na uzyskanie zdarzeń kółka myszy (nie mówiąc o scrollzdarzeniach) w jQuery?


1
Szybkie wyszukiwanie znalazło tę wtyczkę, która może pomóc.
Jerad Rose


@thejh opublikował nową odpowiedź na ten temat z wydarzeniami DOM3: stackoverflow.com/a/24707712/2256325
Sergio.


Tylko uwaga na ten temat. Jeśli chcesz tylko wykryć zmiany na wejściu, a nie wykrywa zmian za pomocą kółka myszy, spróbuj$(el).on('input', ...
rybo111

Odpowiedzi:



206
​$(document).ready(function(){
    $('#foo').bind('mousewheel', function(e){
        if(e.originalEvent.wheelDelta /120 > 0) {
            console.log('scrolling up !');
        }
        else{
            console.log('scrolling down !');
        }
    });
});

53
DOMMouseScrollZdarzenie jest używany w FF, więc trzeba wysłuchać obu .bind('DOMMouseScroll mousewheel') {evetns developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/...
mrzmyr

9
e.originalEvent.wheelDeltajest niezdefiniowana w FF23
hofnarwillie

27
Nie musisz dzielić przez 120, to bezużyteczne marnowanie procesora
venimus

6
chyba najlepsza odpowiedź

2
Ale w każdym razie, dlaczego miałbyś chcieć podzielić to przez 120? Co to jest stałe? (Nie musisz, jak wskazał Venimus.)
mshthn

148

Wiązanie z obydwoma mousewheeli DOMMouseScrollskończyło się dla mnie naprawdę dobrze:

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

Ta metoda działa w IE9 +, Chrome 33 i Firefox 27.


Edycja - marzec 2016

Postanowiłem wrócić do tego problemu, ponieważ minęło trochę czasu. Strona MDN dla zdarzenia przewijania ma świetny sposób na pobranie pozycji przewijania, z requestAnimationFramektórej korzysta , co jest wysoce preferowane niż moja poprzednia metoda wykrywania. Zmodyfikowałem ich kod, aby zapewnić lepszą kompatybilność oprócz kierunku przewijania i pozycji:

(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;
  });
})();

Zobacz śledzenie przewijania Pen Vanilla JS autorstwa Jesse Dupuy ( @ blindside85 ) na CodePen .

Ten kod obecnie pracuje w Chrome v50, Firefox v44, Safari v9, and IE9+

Bibliografia:


To zadziałało najlepiej dla mnie. Jednak ten skrypt jest uruchamiany po „kliknięciu” kółka przewijania. W przypadku niektórych skryptów może to być przytłaczające. Czy istnieje sposób traktowania każdego zdarzenia przewijania jako jednej instancji zamiast uruchamiania skryptu po każdym kliknięciu kółkiem przewijania?
zadzwoń

Niespecjalnie. Z tego, co widziałem, wiele osób albo unika zajmowania się śledzeniem przewijania, albo zamiast tego użyje licznika czasu (np. Sprawdzanie pozycji użytkownika na stronie co x milisekund itp.). Jeśli istnieje bardziej wydajne rozwiązanie, zdecydowanie chcę o tym wiedzieć!
Jesse Dupuy

1
Znalazłem sposób, aby to zrobić: stackoverflow.com/questions/23919035/ ...
invot

1
Dziękuję za aktualizację. Czy możesz skopiować kod do odpowiedzi? Nigdy nie wiadomo, czy kodepen kiedyś się zepsuje. To się wydarzyło wcześniej.
JDB nadal pamięta Monikę z

2
@JesseDupuy, zagłosowałbym za tą odpowiedzią, ale Twoja zaktualizowana wersja nie działa, jeśli dokument pasuje do widoku („szerokość: 100vh; wysokość: 100vh”) lub otrzymano „przepełnienie: ukryte;”. „window.addEventListener ('scroll', callback)” nie jest poprawną odpowiedzią na „window.addEventListener ('mousewheel', callback)”.
Daniel

46

Od teraz w 2017 roku możesz po prostu pisać

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

  // deltaY obviously records vertical scroll, deltaX and deltaZ exist too
  if(event.originalEvent.deltaY < 0){
    // wheeled up
  }
  else {
    // wheeled down
  }
});

Działa z obecnymi przeglądarkami Firefox 51, Chrome 56, IE9 +


37

Odpowiedzi dotyczące zdarzenia „mousewheel” odnoszą się do wycofanego zdarzenia. Standardowym wydarzeniem jest po prostu „koło”. Zobacz https://developer.mozilla.org/en-US/docs/Web/Reference/Events/wheel


20
Wypróbowałem te i stwierdziłem: „koło” działa w przeglądarkach Firefox i IE, ale nie w Chrome. „Kółko myszy” działa w przeglądarce Chrome i IE, ale nie w przeglądarce Firefox. „DOMMouseScroll” działa tylko w przeglądarce Firefox.
Curtis Yallop,

1
Whoa, to zaoszczędziło mi dużo czasu. Dzięki!
gustavohenke

4
Wygląda na to, że Chrome dodał obsługę „koła” w sierpniu 2013 r .: code.google.com/p/chromium/issues/detail?id=227454
rstackhouse,

2
Safari nadal nie obsługuje zdarzenia koła.
Thayne,

Jak mówi twoja dokumentacja, wheelzdarzenie jest obsługiwane na Edge nie, IEco nie jest tym samym. CanIuse
Alex

16

To zadziałało dla mnie :)

 //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;
 });

z przepełnienia stosu


14

Oto rozwiązanie waniliowe. Może być używany w jQuery, jeśli zdarzenie przekazane do funkcji jest tym, event.originalEventktóre jQuery udostępnia jako właściwość zdarzenia jQuery. Lub jeśli wewnątrz callbackfunkcji poniżej dodamy przed pierwszą linią:event = event.originalEvent; .

Ten kod normalizuje prędkość / wielkość kółka i jest dodatni dla tego, co byłoby przewijaniem do przodu w typowej myszy i ujemny dla ruchu kółka myszy do tyłu.

Demo: 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);

Jest też wtyczka do jQuery, która jest bardziej rozwlekła w kodzie i trochę więcej cukru: https://github.com/brandonaaron/jquery-mousewheel


8

Działa to we wszystkich najnowszych wersjach IE, Firefox i Chrome.

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

5

Utknąłem dzisiaj w tym problemie i stwierdziłem, że ten kod działa dobrze

$('#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');
    }
});

4

użyj tego kodu

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

0

moja kombinacja wygląda tak. zanika i zanika przy każdym przewijaniu w dół / w górę. w przeciwnym razie musisz przewinąć w górę do nagłówka, aby go zaniknąć.

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);
    }
});

powyższy nie jest zoptymalizowany pod kątem dotyku / telefonu komórkowego, myślę, że ten działa lepiej dla wszystkich telefonów komórkowych:

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;

});

0

Wtyczka, którą opublikował @DarinDimitrov jquery-mousewheel, jest zepsuta w jQuery 3+ . Byłoby bardziej wskazane użyciejquery-wheel który działa z jQuery 3+.

Jeśli nie chcesz korzystać z trasy jQuery, MDN bardzo ostrzega przed użyciem mousewheelzdarzenia, ponieważ jest ono niestandardowe i nie jest obsługiwane w wielu miejscach. Zamiast tego mówi, że powinieneś używać wheelzdarzenia, ponieważ uzyskujesz znacznie większą dokładność w zakresie dokładnych wartości, które otrzymujesz. Jest obsługiwany przez większość głównych przeglądarek.


0

Jeśli używasz wspomnianej wtyczki jquery mousewheel , to co powiesz na użycie drugiego argumentu funkcji obsługi zdarzeń - delta:

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

-3

Niedawno mam ten sam problem, gdzie $(window).mousewheelwracałemundefined

To, co zrobiłem, było $(window).on('mousewheel', function() {});

Do dalszego przetwarzania używam:

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

    if (event.type === 'mousewheel') {
        if (yourFunctionForGetMouseWheelDirection(event) > 0) {
            direction = 'up';
        } else {
            direction = 'down';
        }
    }
}

Nie powiedziałeś, co ma newUtilities.getMouseWheelDirection
ccsakuweb

To jest poza zakresem tego pytania. Więc to nie jest kopiuj wklej witrynę.
Szymon Toda
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.