ФорумПрограммированиеJavaScript → Обработка событий колёсика мыши

Обработка событий колёсика мыши

  • SHtoRM

    Сообщения: 22 Репутация: N Группа: Кто попало

    Spritz 31 января 2011 г. 12:51

    Здравствуйте!
    Столкнулся с необходимостью определить, в какую сторону крутится колёсико мыши на определённом объекте и в зависимости от этого вызывать функцию in() или out(). Казалось бы, ерунда, но в инете на эту тему инфы сравнительно мало. Нашёл работающий кроссбраузерный скрипт, но делаю что-то не так ( помогите пожалуйста разобраться …


    <div id="gwxim" onmouseover="setHook(this,1);" onmouseout="setHook(this);"></div>




    //——————————————————————
    // Функция установки обработчика события
    // Параметры вызова:
    // hElem - DOM-элемент или его ID
    // eventName - событие
    // callback - функция, которая будет вызвана при событии
    // На выходе:
    // TRUE - обработчик установлен
    // FALSE - элемент не найден или браузер не поддерживает события
    //——————————————————————
    function hookEvent(hElem, eventName, callback) {
    if (typeof(hElem) == 'string') {
    // Если передан ID, то получить DOM-элемент
    hElem = document.getElementById(hElem);
    }
    // Если такого элемента нет, то возврат с ошибкой
    if (!hElem) { return false; }

    if (hElem.addEventListener) {
    if (eventName == 'mousewheel') {
    // Событие вращения колесика для Mozilla
    hElem.addEventListener('DOMMouseScroll', callback, false);
    }
    // Колесико для Opera, WebKit-based, а также любые другие события
    // для всех браузеров кроме Internet Explorer
    hElem.addEventListener(eventName, callback, false);
    }
    else if (hElem.attachEvent) {
    // Все события для Internet Explorer
    hElem.attachEvent('on' + eventName, callback);
    }
    else { return false; }
    return true;
    }


    //——————————————————————
    // Функция снятия обработчика события
    // Параметры вызова:
    // hElem - DOM-элемент или его ID
    // eventName - событие
    // callback - функция обработки события, которую надо отменить
    //——————————————————————
    function unhookEvent(hElem, eventName, callback) {
    if (typeof(hElem) == 'string') {
    // Если передан ID, то получить DOM-элемент
    hElem = document.getElementById(hElem);
    }
    // Если такого элемента нет, то возврат с ошибкой
    if (!hElem) { return false; }

    if (hElem.removeEventListener) {
    if (eventName == 'mousewheel') {
    // Событие вращения колесика для Mozilla
    hElem.removeEventListener('DOMMouseScroll', callback, false);
    }
    // Колесико для Opera, WebKit-based, а также любые другие события
    // для всех браузеров кроме Internet Explorer
    hElem.removeEventListener(eventName, callback, false);
    }
    else if (hElem.detachEvent) {
    // Все события для Internet Explorer
    hElem.detachEvent('on' + eventName, callback);
    }
    else { return false; }
    return true;
    }


    //——————————————————————
    // Кроссбраузерная функция подавления события
    //——————————————————————
    function cancelEvent(e) {
    e = e ? e : window.event;
    if (e.stopPropagation) {
    e.stopPropagation();
    }
    if (e.preventDefault) {
    e.preventDefault();
    }
    e.cancelBubble = true;
    e.cancel = true;
    e.returnValue = false;
    return false;
    }


    // Установка и снятие обработчика колеса мыши
    function setHook(obj, act) {
    act ? hookEvent(obj.id, 'mousewheel', MouseWheelFunction) : unhookEvent(obj.id, 'mousewheel', MouseWheelFunction);
    }

    // Функция реагирования
    function MouseWheelFunction(e) {
    e = e ? e : window.event;

    var wheelElem = e.target ? e.target : e.srcElement;
    var wheelData = e.detail ? e.detail * -1 : e.wheelDelta / 40;
    // В движке WebKit возвращается значение в 100 раз больше
    if (Math.abs(wheelData)>100) { wheelData=Math.round(wheelData/100); }

    // Теперь в переменной 'wheelElem' содержится элемент, который перехватил колесо
    // мыши, а в 'wheelData' значение поворота колеса


    if (wheelData > 0){
    in();
    }
    else{
    out();
    }

    // Отменить штатные действия браузера при кручении колеса мыши
    return cancelEvent(e);
    }


    В зависимости от значения wheelData я вызываю свою функцию обработки. Но на практике получается, что функция вызывается на каждое деление скролла. То есть, если сильно крутануть колёсико, то получим много вызовов подряд функции in() или out(). Хотелось бы независимо от того, сильно крутанули скролл или на одно деление, получить 1 вызов функции обработки. Подскажите пожалуйста как это сделать?
  • master

    Сообщения: 3244 Репутация: N Группа: Джедаи

    Spritz 31 января 2011 г. 14:50, спустя 1 час 59 минут 13 секунд

    заебись идея. пришёл на сайт, крутишь-крутишь колёсико, а прокрутка работает еле-еле. думаешь "может мышь сломалась?" потом выясняется что это сайт такой. плюёшь, закрываешь
    не всё полезно, что в swap полезло
  • SHtoRM

    Сообщения: 22 Репутация: N Группа: Кто попало

    Spritz 31 января 2011 г. 15:06, спустя 15 минут 41 секунду

    Мне этот скрипт нихера не для прокрутки нужен. Нужен факт прогрутки вверх или вниз. А сколько крутили - пофиг. Подскажите лучше по теме.
  • SHtoRM

    Сообщения: 22 Репутация: N Группа: Кто попало

    Spritz 31 января 2011 г. 15:23, спустя 17 минут 3 секунды

    Или же чтобы 1 раз возвращал на сколько крутанули колёсико. А здесь на каждый сдвиг срабатывает функция… не совсем то что нужно %)
    можно другие решения, в том числе на jquery …
  • SHtoRM

    Сообщения: 22 Репутация: N Группа: Кто попало

    Spritz 31 января 2011 г. 16:44, спустя 1 час 21 минуту 7 секунд

    Всем спасибо, сам нашёл решение…
  • Абырвалг

    Сообщения: 6480 Репутация: N Группа: Джедаи

    Spritz 31 января 2011 г. 16:47, спустя 2 минуты 21 секунду

    так поведай миру о нем
  • SHtoRM

    Сообщения: 22 Репутация: N Группа: Кто попало

    Spritz 31 января 2011 г. 17:49, спустя 1 час 2 минуты 4 секунды

    Решение примитивное, но работает.
    создал скрытый input

    <input type="hidden" id="fzm" value="0"/>


    а в функции обработки события поставил проверку на значение … если 0, то функция срабатывает и меняет значение инпута с 0 на 1, а потом через секунду обратно на 0. Если значение 1, то возвращаем false. Врядли кто-то крутит скролл больше 1 секунды …

    	if (jQuery('#fzm').val() == 1){
    return(false);
    }
    jQuery('#fzm').attr('value', '1');
    var timerOnce = window.setTimeout("runOnce();", 1000);


    function runOnce(){
    jQuery('#fzm').attr('value', '0');
    }


    Получаем за одну прокрутку одну функцию обработки. Хотя в идеале хотелось бы конечн как-то узнать на сколько крутанули скролл и потом только вызвать функцию, но такое решение мне тоже пойдёт пока что…

Пожалуйста, авторизуйтесь, чтобы написать комментарий!