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

Ловим скролл

4 мая 2008, 20:19

Страницы сайтов по своему функционалу стремятся к возможностям полноценных приложений, что, в основном, ложится на плечи 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, 08:43
Ответить

bur

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

shostak

А как заблокировать дефолтную обработку браузером, прокрутку страницы, только если курсор находится над определённым элементом? Как в Яндекс.Фотках.
Т.е., чтобы когда курсор находится над списком фотографий работала прокрутка фотографий, а когда вне списка — прокрутка страницы.
11.11.2008, 12: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>


Как-то так, проверьте.
11.11.2008, 12:44
Ответить
NO USERPIC

shostak

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

bur

Повесьте всё те же mouseover и mousemove на превью.
11.11.2008, 14:05
Ответить
NO USERPIC

shostak

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

bur

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

shostak

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

Kamikaze

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

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

bur

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

Kamikaze

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

betaboy

Подскажите как сделать такой эффект скролла: http://emfire.ru/
10.07.2010, 19:50
Ответить
NO USERPIC

Devious

Наверно дико поднимать такую старую тему,но к сожалению же который день не могу решить одну проблему..
Суть такова:
есть длинная страница адаптивного сайта.В середине этой простыни есть блок с несколькими абзацами текста.когда доезжаем до этого блока нужно заблокировать дефолтную прокрутку и начать выводить абзацы по одному(в смысле сначала появится первый,потом к нему подъедет второй и т.д.)
собственно проблема в том,что ваш пример блочит только события мышки,а как повторить подобный трюк на тач устройстве?
Буду крайне признательна за любые подсказки или советы.
З.Ы. думала сделать деградацию кода для тач устройств,да только в связи с появлением тач-компов(в смысле фиг угадаешь,с мышкой будут сидеть на сайте или пальцем водить) стратегию поведения в голове уложить не могу.
09.12.2013, 12:02
Ответить

1234ru

На touch-устройствах не проверял, но, кажется, есть гораздо более простой вариант: поставьте блоку с абзацами текста фиксированную высоту (если не стоит) и overflow:scroll. Тогда будет ровно так, как вы пишете:

Devious
когда доезжаем до этого блока нужно заблокировать дефолтную прокрутку и начать выводить абзацы по одному

Попробуйте для примера вот такой код:

<!DOCTYPE HTML>
<html>
<head>
    <title></title>
</head>
<body>
    <style>
        body > div {
            height: 1000px;
            margin: 200px;
            background-color: #E0E0E0;
            overflow-y: scroll;
        }
       
        div > div {
            height: 1500px;
        }
    </style>
   
    <div>
        <div>(вместо этого div - абзацы длинного текста)</div>
    </div>
</body>
</html>

Работает ли так, как вам нужно?
То, что не убивает нас, делает нас инвалидами.
09.12.2013, 16:44
Ответить
NO USERPIC

Devious

К сожалению,не подойдет.во-первых появляется вторая полоса прокрутки. Хотя,конечно,можно помудрить и избавиться от нее, но самый большой минус такого подхода,что мышка или палец(на тач устройстве) может инициировать скролл вне этого блока(сверху,снизу) и тогда посетитель не увидит контент,который анимируется в конце прокрутки блока.Наверно придется все-таки идти на какой-то компромисс дизайнеру и сделать все немного иначе.Спасибо
10.12.2013, 08:16
Ответить
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
© 2008—2017 webew.ru, связаться: x собака webew.ru
Сайт использует Flede и соответствует стандартам WAI-WCAG 1.0 на уровне A.
Rambler's Top100

Реклама: