Конспект JS-course

Колёсико мыши: "wheel" и аналоги

Источник: http://learn.javascript.ru/mousewheel

Отличия колёсика от прокрутки

Несмотря на то, что колёсико мыши обычно ассоциируется с прокруткой, это совсем разные вещи.

  • При прокрутке срабатывает событие onscroll — рассмотрим его в дальнейшем. Оно произойдёт при любой прокрутке, в том числе через клавиатурy, но только на прокручиваемых элементах. Например, элемент с overflow: hidden в принципе не может сгенерировать onscroll.
  • А событие wheel является чисто «мышиным». Оно генерируется над любым элементом при передвижении колеса мыши. При этом не важно, прокручиваемый он или нет. В частности, overflow:hidden никак не препятствует обработке колеса мыши.

Кроме того, событие onscroll происходит после прокрутки, а onwheel — до прокрутки, поэтому в нём можно отменить саму прокрутку (действие браузера).

Зоопарк wheel в разных браузерах

Самые важные свойства современного события и его нестандартных аналогов:

  • wheel
    • Свойство deltaY — количество прокрученных пикселей по горизонтали и вертикали. Существуют также свойства deltaX и deltaZ для других направлений прокрутки.
  • MozMousePixelScroll
    • Срабатывает, начиная с Firefox 3.5, только в Firefox. Даёт возможность отменить прокрутку и получить размер в пикселях через свойство detail, ось прокрутки в свойстве axis.
  • DOMMouseScroll
    • Существует в Firefox очень давно, отличается от предыдущего тем, что даёт в detail количество строк. Если не нужна поддержка Firefox < 3.5, то не нужно и это событие.
  • mousewheel
    • Срабатывает в браузерах, которые ещё не реализовали wheel. В свойстве wheelDelta — условный «размер прокрутки», обычно равен 120 для прокрутки вверх и -120 — вниз. Он не соответствует какому-либо конкретному количеству пикселей.

Чтобы кросс-браузерно отловить прокрутку и, при необходимости, отменить её, можно использовать все эти события.

Пример:

if (elem.addEventListener) {
  if ('onwheel' in document) {
    // IE9+, FF17+
    elem.addEventListener ("wheel", onWheel, false);
  } else if ('onmousewheel' in document) {
    // устаревший вариант события
    elem.addEventListener ("mousewheel", onWheel, false);
  } else {
    // 3.5 <= Firefox < 17, более старое событие DOMMouseScroll пропустим
    elem.addEventListener ("MozMousePixelScroll", onWheel, false);
  }
} else { // IE<9
  elem.attachEvent ("onmousewheel", onWheel);
}

function onWheel(e) {
  e = e || window.event;

  // wheelDelta не дает возможность узнать количество пикселей
  var delta = e.deltaY || e.detail || e.wheelDelta;

  var info = document.getElementById('delta');

  info.innerHTML = +info.innerHTML + delta;

  e.preventDefault ? e.preventDefault() : (e.returnValue = false);
}