webew
Войти » Регистрация
 
JavaScript :: События

Ловим скролл

5 мая 2008, 0:19
Автор: Александр Бурцев [bur]

Страницы сайтов по своему функционалу стремятся к возможностям полноценных приложений, что, в основном, ложится на плечи JavaScript. Одна из задач, которая возникает у разработчика JavaScript-приложений — обработка скролла.

Пара примеров:

Для эффективной работы со скроллом необходимо решить следующие задачи:

  1. Поймать событие скролла.
  2. Определить направление.
  3. Заблокировать дефолтную обработку браузером — прокрутку страницы.

Для отлова скролла понадобится функция для добавления обработчика событий.

Код

// Функция для добавления обработчика событий
function addHandler(object, event, handler, useCapture) {
    if (object.addEventListener) {
        object.addEventListener(event, handler, useCapture ? useCapture : false);
    } else if (object.attachEvent) {
        object.attachEvent('on' + event, handler);
    } else alert("Add handler is not supported");
}
// Добавляем обработчики
/* Gecko */
addHandler(window, 'DOMMouseScroll', wheel);
/* Opera */
addHandler(window, 'mousewheel', wheel);
/* IE */
addHandler(document, 'mousewheel', wheel);
// Обработчик события
function wheel(event) {
    var delta; // Направление скролла
    // -1 - скролл вниз
    // 1  - скролл вверх
    event = event || window.event;
    // Opera и IE работают со свойством wheelDelta
    if (event.wheelDelta) {
        delta = event.wheelDelta / 120;
        // В Опере значение wheelDelta такое же, но с противоположным знаком
        if (window.opera) delta = -delta;
    // В реализации Gecko получим свойство detail
    } else if (event.detail) {
        delta = -event.detail / 3;
    }
    // Запрещаем обработку события браузером по умолчанию
    if (event.preventDefault)  event.preventDefault();
    event.returnValue = false;
    return delta;
}

Пример

Нажмите на эту ссылку для активации примера и попробуйте проскроллить страницу :-).

При правильной работе будет выводиться алерт с направлением скролла без прокрутки страницы.


© Все права на данную статью принадлежат порталу webew.ru. Перепечатка в интернет-изданиях разрешается только с указанием автора и прямой ссылки на оригинальную статью. Перепечатка в печатных изданиях допускается только с разрешения редакции.
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
NO USERPIC

rgbeast

В примере кода пропущен вызов функции alert(), хотя он есть в работающем коде на странице. Ссылка активирующая код имеет href="#js::init", есть ли от этого какая-то польза? Кстати, по стандарту RFC-3986, во фрагмент после # не должно быть символа двоеточие http://www.ietf.org/rfc/rfc3986.txt
05.05.2008, 12:43
Ответить

bur

Код примера в демонстрационных целях действительно был изменен. Кроме алерта обработчики событий в примере устанавливаются по клику, иначе страницу сразу после загрузки невозможно было бы скроллить, что неудобно для чтения статьи.
А насчет хрефа — никакой смысловой нагрузки указанная там внутренняя ссылка не несет. Спасибо за уточнение по двоеточиям.
Fastcoder.org — портал для JavaScrpt-программистов
05.05.2008, 20:46
Ответить
NO USERPIC

shostak

А как заблокировать дефолтную обработку браузером, прокрутку страницы, только если курсор находится над определённым элементом? Как в Яндекс.Фотках.
Т.е., чтобы когда курсор находится над списком фотографий работала прокрутка фотографий, а когда вне списка — прокрутка страницы.
11.11.2008, 15:14
Ответить

bur

Следите за элементом, над которым находится курсор мыши. Например, вы хотите блокировать скролл только, если юзер навел указатель мыши на <div class="blockscroll">, тогда в упрощенном решении заводим глобальную переменную, на состояние которой будет смотреть в ф-ии wheel из статьи:

Код JavaScript:

var blockScroll = false; // Флаг, указывающий нужно ли блокировать скролл страницы
function addHandler(object, event, handler, useCapture) {
    if (object.addEventListener)
        object.addEventListener(event, handler, useCapture ? useCapture : false);
    else if (object.attachEvent)
        object.attachEvent('on' + event, handler);
}
addHandler(window, 'DOMMouseScroll', wheel);
addHandler(window, 'mousewheel', wheel);
addHandler(document, 'mousewheel', wheel);
function wheel(event) {
    var delta;
    event = event || window.event;
    if (event.wheelDelta) {
        delta = event.wheelDelta / 120;
        if (window.opera) delta = -delta;
    } else if (event.detail) {
        delta = -event.detail / 3;
    }
    if (blockScroll) { // !!!!!!!!!!!!! NEW !!!!!!!!!!!!!
        if (event.preventDefault)  event.preventDefault();
        event.returnValue = false;
    }
    return delta;
}


Код HTML:

<div class="blockscroll" onmouseover="blockScroll=true;" onmousemove="blockScroll=true;" onmouseout="blockScroll=false;"></div>


Как-то так, проверьте.
Fastcoder.org — портал для JavaScrpt-программистов
11.11.2008, 15:44
Ответить
NO USERPIC

shostak

Красивое решение! Огромное спасибо!
Единственный момент — когда курсор заходит на изображение превью фотографии, у родительского блока срабатывает событие onmouseout и соответственно происходит частичная прокрутка страницы.
Побороть пока не удалось. Буду благодарен, если поскажете решение этой проблемы.
11.11.2008, 17:01
Ответить

bur

Повесьте всё те же mouseover и mousemove на превью.
Fastcoder.org — портал для JavaScrpt-программистов
11.11.2008, 17:05
Ответить
NO USERPIC

shostak

Не помогло.
Кстати, эта проблема наблюдается только в IE.
11.11.2008, 17:32
Ответить

bur

Да, вспомнил, есть такая беда.
Я решил эту проблему для ИЕ методом "в лоб". Не самый красивый способ, наверняка есть более аккуратный фикс.
Алгоритм такой:
1) Определить координаты HTML-элемента на странице, а также длину и высоту элемента.
2) Определить координаты указателя мыши.
3) По координатам (несколько условий) смотреть где находится указатель мыши и ставить значение для переменной blockScroll.
Fastcoder.org — портал для JavaScrpt-программистов
11.11.2008, 17:37
Ответить
NO USERPIC

shostak

Понятно. Попробую сделать так. Ещё раз спасибо!
11.11.2008, 18:38
Ответить
NO USERPIC

Kamikaze

Подскажите пожалуйста начинающему програмеру в области джаваскрипта )

Каким образом заставить вышеидущий код работать? если вам не сложно - можете написать пример, что и куда надо копипастить, чтоб заработало.
заранее спасибо
15.12.2008, 23:10
Ответить

bur

Подскажем, если объясните что конкретно у вас не работает.
В конце статьи есть пример с вызовом функции, видели?
Fastcoder.org — портал для JavaScrpt-программистов
17.12.2008, 12:48
Ответить
NO USERPIC

Kamikaze

всё, разобрался )
спасибо большое, отличный скрипт!
18.12.2008, 10:40
Ответить
NO USERPIC

betaboy

Подскажите как сделать такой эффект скролла: http://emfire.ru/
10.07.2010, 23:50
Ответить
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
© 2007—2012 webew.ru, связаться: x собака webew.ru
Сайт использует Flede и соответствует стандартам WAI-WCAG 1.0 на уровне A.
Rambler's Top100