Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 15.11.2014, 17:34
Аспирант
Отправить личное сообщение для Andrew K Посмотреть профиль Найти все сообщения от Andrew K
 
Регистрация: 15.11.2014
Сообщений: 50

Как узнать сколько пользователь прокрутил пикселей без прокрутки страницы
Здравствуйте. Мне нужно реализовать следующий эффект. Когда пользователь докручивает до определенного места страницы запускается анимация. Если пользователь прокручивает дальше, то анимация проигрывается вперед, если крутит назад, то анимация проигрывается назад. Скорость анимации определяется скоростью прокрутки мыши. При этом страница не должна прокручиваться.

Чтобы реализовать такое поведение я помещаю прозрачный див с абсолютным позиционированием над блоком с анимацией. В стилях дива стоит overflow : auto. В этот див вставлен другой див заведомо большего размера, который и будет прокручиваться при прокрутке страницы. При этом сама страница будет стоять на месте. В зависимости от уже прокрученной области анимация идет вперед или назад:
<!doctype html>
<html lang="ru">
<head>
    <style type="text/css">
        .animation-div{
            height: 600px;
            background-color: #ffff00;
        }
        .orange{
            background-color: orange;
        }
        .red{
            background-color: red;
        }

        .hidden-div{
            position: absolute;
            top: 400px;
            left: 0;
            width: 100%;
            height: 600px;
            overflow: auto;
            opacity: .0;
            background-color: blue;

        }
        .hidden-div div{
            height: 1200px;
            width: 60%;
        }
    </style>

</head>
<body>
<div class="hidden-div test2">
    <div></div>
</div>

<div style="height: 400px; background-color: ghostwhite"></div>

<div class="animation-div">
    Див где будет происходить анимация. Но текст нельзя выделить.
    <a href="#">На ссылку нельзя нажать.</a>
</div>

<div style="height: 400px; background-color: ghostwhite"></div>


<script type="text/javascript">

    var hiddenDiv = document.getElementsByClassName('hidden-div')[0],
        animationDiv = document.getElementsByClassName('animation-div')[0],
        counter = 0;

    hiddenDiv.onscroll = function(){
        counter = hiddenDiv.scrollTop
        console.log(counter);

        if(counter > 0 && counter < 200) animationDiv.className = 'animation-div';
        if(counter > 200 && counter < 400) animationDiv.className = 'animation-div orange';
        if(counter > 400 && counter < 600) animationDiv.className = 'animation-div red';
    }
</script>
</body>
</html>


Проблема в том, что на элементы, которые накрывает прозрачный див, нельзя нажать или выделить. Как можно реализовать аналогичное поведение, но без использования накрывающего прозрачного дива. Или же с ним, но чтобы с элементами можно было взаимодействовать.

Последний раз редактировалось Andrew K, 17.11.2014 в 20:00.
Ответить с цитированием
  #2 (permalink)  
Старый 15.11.2014, 17:53
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

Событие scroll - прокрутка страницы. Прокрутка может быть вызвана не только колесиком мыши, но и выделением, кликом по колесику, клавишами клавиатуры, touch - действиями и тд и тп.


Тебе по ходу нужно другое событие - wheel - прокрутка колесика мыши (для тачпадов тоже оно вызывается, но для touch-устройств нужно слушать touch/pointer события). Притом, его можно отменить и страница не будет прокручена.


С wheel гемор. Для старых браузеров нужно юзать устаревшие события - mousewheel и DOMMouseScroll. Выдают они тоже разные значения. По сути кроссбраузерно и кроссплатформенно нельзя узнать как сильно крутанули колесико.


Для jQuery есть плагин, избавляющий от геморроя. Может есть и vanilla js плагин.
__________________
В личку только с интересными предложениями
Ответить с цитированием
  #3 (permalink)  
Старый 15.11.2014, 17:55
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

Сообщение от Andrew K
getElementsByClassName
Кстати не работает в IE8, хотя можно заменить на querySelector(), который работает.
__________________
В личку только с интересными предложениями
Ответить с цитированием
  #4 (permalink)  
Старый 15.11.2014, 19:56
Аспирант
Отправить личное сообщение для Andrew K Посмотреть профиль Найти все сообщения от Andrew K
 
Регистрация: 15.11.2014
Сообщений: 50

Про событие wheel забыл. Спасибо, что напомнили. Вот такой код получился:
<!doctype html>
<html lang="ru">
<head>
    <style type="text/css">
        .animation-div{
            height: 600px;
            background-color: #ffff00;
        }
        .orange{
            background-color: orange;
        }
        .red{
            background-color: red;
        }
    </style>

</head>
<body>

<div style="height: 400px; background-color: ghostwhite"></div>

<div class="animation-div">
    Див где будет происходить анимация. <a href="#">Ссылка</a>
</div>

<div style="height: 400px; background-color: ghostwhite"></div>


<script type="text/javascript">
    var totalWheel = 0,
        animationDiv = document.getElementsByClassName('animation-div')[0]

    window.onwheel = function(e){
        var delta = e.deltaY;
        totalWheel += delta // Сколько всего прокрутили

        if(totalWheel > 400 && totalWheel < 700){
            window.onscroll = function(e) {
                window.scrollTo(0, 400)
            }

            if(totalWheel > 400 && totalWheel < 500) animationDiv.className = 'animation-div';
            if(totalWheel > 500 && totalWheel < 600) animationDiv.className = 'animation-div orange';
            if(totalWheel > 600 && totalWheel < 700) animationDiv.className = 'animation-div red';

        }else{
            window.onscroll = null; // Обнуление предыдущего обработчика события onscroll
        }
    }
</script>
</body>
</html>


Почему-то событие scroll нельзя отменить. Этот код не работает:
window.onscroll = function(e) {
        e.preventDefault()
    }


Поэтому я прокручивал страницу до определенного значения:
window.onscroll = function(e) {
                window.scrollTo(0, 400)
            }

Последний раз редактировалось Andrew K, 17.11.2014 в 20:00.
Ответить с цитированием
  #5 (permalink)  
Старый 15.11.2014, 19:57
Аспирант
Отправить личное сообщение для Andrew K Посмотреть профиль Найти все сообщения от Andrew K
 
Регистрация: 15.11.2014
Сообщений: 50

Сообщение от danik.js Посмотреть сообщение
Кстати не работает в IE8, хотя можно заменить на querySelector(), который работает.
Я хочу понять общий ход написания сценария, поэтому над кроссбраузерностью пока не думал.
Ответить с цитированием
  #6 (permalink)  
Старый 15.11.2014, 20:12
Аспирант
Отправить личное сообщение для Andrew K Посмотреть профиль Найти все сообщения от Andrew K
 
Регистрация: 15.11.2014
Сообщений: 50

Сообщение от danik.js Посмотреть сообщение
Может есть и vanilla js плагин.
Оценил ваш искрометный юмор.
Ответить с цитированием
  #7 (permalink)  
Старый 15.11.2014, 20:20
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

Сообщение от Andrew K
Оценил ваш искрометный юмор.
Нет тут никакого юмора )
Сообщение от Andrew K
Почему-то событие scroll нельзя отменить. Этот код не работает:
И не должен. Событие происходит постфактум и отменить его уже нельзя.

Не понимаю чего хочешь добиться. Добавляй атрибут run в тег [ HTML ], чтоб можно было запустить:
<body></body>
__________________
В личку только с интересными предложениями
Ответить с цитированием
  #8 (permalink)  
Старый 15.11.2014, 20:32
Аспирант
Отправить личное сообщение для Andrew K Посмотреть профиль Найти все сообщения от Andrew K
 
Регистрация: 15.11.2014
Сообщений: 50

Сообщение от danik.js Посмотреть сообщение
Нет тут никакого юмора )
Не понимаю чего хочешь добиться. Добавляй атрибут run в тег [ HTML ], чтоб можно было запустить:
<body></body>
Что вы имели в виду? Что запустить?
Ответить с цитированием
  #9 (permalink)  
Старый 16.11.2014, 11:41
Аспирант
Отправить личное сообщение для Andrew K Посмотреть профиль Найти все сообщения от Andrew K
 
Регистрация: 15.11.2014
Сообщений: 50

Мой предыдущий код содержал ошибки и на работал, если пользователь прокручивал страницу с помощью ползунка. Вот этот работает лучше:
<!doctype html>
<html lang="ru">
<head>
    <style type="text/css">
        .animation-div{
            height: 300px;
            background-color: #ffff00;
        }
        .orange{
            background-color: orange;
        }
        .red{
            background-color: red;
        }
    </style>
</head>
<body>

<div style="height: 300px; background-color: ghostwhite"></div>
<div class="animation-div">Див где будет происходить анимация.</div>
<div style="height: 600px; background-color: ghostwhite"></div>

<script type="text/javascript">

    var animationDiv = document.getElementsByClassName('animation-div')[0],
        count = 0;

    function wheelMove(e){
        if(document.body.scrollTop > 300 && document.body.scrollTop < 350){
            var delta = e.deltaY
            count += delta

            if(count < 1) count = 0
            if(count > 299) count = 300

            if(count > 0 && count < 300){
                e.preventDefault()
            }

            if(count > 0 && count < 100) animationDiv.className = 'animation-div';
            if(count > 100 && count < 200) animationDiv.className = 'animation-div orange';
            if(count > 200 && count < 300) animationDiv.className = 'animation-div red';
        }

    }

    animationDiv.onwheel = wheelMove;


    // Если пользователь прокручивает стараницу не мышкой, а использует ползунок, тогда в зависимости от прокрученной страницы показывается или первый кадр или последний.
    function onscrollAmimation(){
        var currentTop = document.body.scrollTop
        console.log(currentTop);

        if(currentTop < 300){
            animationDiv.className = 'animation-div';
        }else if(currentTop > 350){
            animationDiv.className = 'animation-div red';
        }
    }

    window.onscroll = onscrollAmimation

</script>
</body>
</html>

Последний раз редактировалось Andrew K, 17.11.2014 в 20:01.
Ответить с цитированием
  #10 (permalink)  
Старый 16.11.2014, 11:51
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

Сообщение от Andrew K
Что вы имели в виду?
[HTML run]
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как узнать сколько членов в объекте kdie Общие вопросы Javascript 2 30.09.2009 12:28
Как узнать динамический код страницы? gosha13 Общие вопросы Javascript 5 27.07.2009 13:31
Как узнать, что пользователь не нажимал клавиш strike Общие вопросы Javascript 7 22.07.2009 13:30
Как узнать, что пользователь просматривает страницу? Tumman Events/DOM/Window 1 19.03.2009 18:38
Как сделать смену картинки, типа "до" и "после", без перезагрузки страницы? btstudio Events/DOM/Window 2 23.02.2009 20:43