Как определить направление события прокрутки jQuery? - PullRequest
326 голосов
/ 01 декабря 2010

Я ищу что-то на этот счет:

$(window).scroll(function(event){
   if (/* magic code*/ ){
       // upscroll code
   } else {
      // downscroll code
   }
});

Есть идеи?

Ответы [ 25 ]

651 голосов
/ 01 декабря 2010

Проверить ток scrollTop против предыдущего scrollTop

var lastScrollTop = 0;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
       // downscroll code
   } else {
      // upscroll code
   }
   lastScrollTop = st;
});
162 голосов
/ 11 мая 2012

Вы можете сделать это без необходимости отслеживать предыдущую вершину прокрутки, поскольку все другие примеры требуют:

$(window).bind('mousewheel', function(event) {
    if (event.originalEvent.wheelDelta >= 0) {
        console.log('Scroll up');
    }
    else {
        console.log('Scroll down');
    }
});

Я не эксперт в этом, поэтому не стесняйтесь исследовать это дальше, нопохоже, что при использовании $(element).scroll прослушиваемое событие является событием прокрутки.

Но если вы специально прослушиваете событие mousewheel с помощью bind, атрибут originalEvent параметра события для вашего обратного вызова содержит другую информацию.Часть этой информации wheelDelta.Если оно положительное, вы переместили колесико мыши вверх.Если оно отрицательное, вы переместили колесо мыши вниз.

Я предполагаю, что события mousewheel будут срабатывать при повороте колеса мыши, даже если страница не прокручивается;случай, когда события «прокрутки», вероятно, не запускаются.Если вы хотите, вы можете позвонить event.preventDefault() внизу вашего обратного вызова, чтобы предотвратить прокрутку страницы, и чтобы вы могли использовать событие mousewheel для чего-то другого, кроме прокрутки страницы, например, для некоторого типа функций масштабирования.

28 голосов
/ 18 апреля 2015

Существующее решение

Может быть 3 решения из этой публикации и другой ответ .

Раствор 1

    var lastScrollTop = 0;
    $(window).on('scroll', function() {
        st = $(this).scrollTop();
        if(st < lastScrollTop) {
            console.log('up 1');
        }
        else {
            console.log('down 1');
        }
        lastScrollTop = st;
    });

Решение 2

    $('body').on('DOMMouseScroll', function(e){
        if(e.originalEvent.detail < 0) {
            console.log('up 2');
        }
        else {
            console.log('down 2');
        }
    });

Решение 3

    $('body').on('mousewheel', function(e){
        if(e.originalEvent.wheelDelta > 0) {
            console.log('up 3');
        }
        else {
            console.log('down 3');
        }
    });

Мультибраузерный тест

Я не смог проверить это в Safari

Chrome 42 (Win 7)

  • Решение 1
    • Up: 1 событие на 1 свиток
    • Вниз: 1 событие на 1 свиток
  • Soltion 2
    • Вверх: не работает
    • Вниз: не работает
  • Решение 3
    • Up: 1 событие на 1 свиток
    • Вниз: 1 событие на 1 свиток

Firefox 37 (Win 7)

  • Решение 1
    • Up: 20 событий за 1 свиток
    • Вниз: 20 событий на 1 свиток
  • Soltion 2
    • Вверх: не работает
    • Вниз: 1 событие на 1 свиток
  • Решение 3
    • Вверх: не работает
    • Вниз: не работает

IE 11 (Win 8)

  • Решение 1
    • Вверх: 10 событий на 1 прокрутку (побочный эффект: наконец-то произошла прокрутка вниз)
    • Вниз: 10 событий на 1 свиток
  • Soltion 2
    • Вверх: не работает
    • Вниз: не работает
  • Решение 3
    • Вверх: не работает
    • Вниз: 1 событие на 1 свиток

IE 10 (Win 7)

  • Решение 1
    • Up: 1 событие за 1 свиток
    • Вниз: 1 событие на 1 свиток
  • Soltion 2
    • Вверх: не работает
    • Вниз: не работает
  • Решение 3
    • Up: 1 событие за 1 свиток
    • Вниз: 1 событие на 1 свиток

IE 9 (Win 7)

  • Решение 1
    • Up: 1 событие на 1 свиток
    • Вниз: 1 событие на 1 свиток
  • Soltion 2
    • Вверх: не работает
    • Вниз: не работает
  • Решение 3
    • Up: 1 событие за 1 свиток
    • Вниз: 1 событие на 1 свиток

IE 8 (Win 7)

  • Решение 1
    • Вверх: 2 события на 1 прокрутку (побочный эффект: наконец-то произошла прокрутка вниз)
    • Вниз: 2 ~ 4 события за 1 свиток
  • Soltion 2
    • Вверх: не работает
    • Вниз: не работает
  • Решение 3
    • Up: 1 событие за 1 свиток
    • Вниз: 1 событие на 1 свиток

Комбинированное решение

Я проверил, что побочный эффект от IE 11 и IE 8 исходит из оператора if else. Итак, я заменил его на if else if заявление следующим образом.

Из мультибраузерного теста я решил использовать Solution 3 для обычных браузеров и Solution 1 для Firefox и IE 11.

Я сослался на этот ответ , чтобы обнаружить IE 11.

    // Detect IE version
    var iev=0;
    var ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent));
    var trident = !!navigator.userAgent.match(/Trident\/7.0/);
    var rv=navigator.userAgent.indexOf("rv:11.0");

    if (ieold) iev=new Number(RegExp.$1);
    if (navigator.appVersion.indexOf("MSIE 10") != -1) iev=10;
    if (trident&&rv!=-1) iev=11;

    // Firefox or IE 11
    if(typeof InstallTrigger !== 'undefined' || iev == 11) {
        var lastScrollTop = 0;
        $(window).on('scroll', function() {
            st = $(this).scrollTop();
            if(st < lastScrollTop) {
                console.log('Up');
            }
            else if(st > lastScrollTop) {
                console.log('Down');
            }
            lastScrollTop = st;
        });
    }
    // Other browsers
    else {
        $('body').on('mousewheel', function(e){
            if(e.originalEvent.wheelDelta > 0) {
                console.log('Up');
            }
            else if(e.originalEvent.wheelDelta < 0) {
                console.log('Down');
            }
        });
    }
28 голосов
/ 01 декабря 2010

Сохраните предыдущую позицию прокрутки, а затем посмотрите, больше или меньше новая.

Вот способ избежать любых глобальных переменных ( здесь доступна скрипта ):

(function () {
    var previousScroll = 0;

    $(window).scroll(function(){
       var currentScroll = $(this).scrollTop();
       if (currentScroll > previousScroll){
           alert('down');
       } else {
          alert('up');
       }
       previousScroll = currentScroll;
    });
}()); //run this anonymous function immediately
12 голосов
/ 03 января 2015

Я понимаю, что уже был принят ответ, но хотел опубликовать то, что я использую, на случай, если это может кому-нибудь помочь.Я получаю направление как cliphex с событием mousewheel, но с поддержкой Firefox.Это полезно делать таким образом, если вы делаете что-то вроде блокировки прокрутки и не можете получить текущую вершину прокрутки.

Смотрите живую версию здесь .

$(window).on('mousewheel DOMMouseScroll', function (e) {

    var direction = (function () {

        var delta = (e.type === 'DOMMouseScroll' ?
                     e.originalEvent.detail * -40 :
                     e.originalEvent.wheelDelta);

        return delta > 0 ? 0 : 1;
    }());

    if(direction === 1) {
       // scroll down
    }
    if(direction === 0) {
       // scroll up
    }
});
8 голосов
/ 18 июля 2014

Событие прокрутки

Событие прокрутки ведет себя странно в FF (оно запускается много раз из-за плавной прокрутки), но работает.

Примечание: Событие scroll на самом деле вызывается при перетаскивании полосы прокрутки с помощью клавиш курсора или колеса мыши.

//creates an element to print the scroll position
$("<p id='test'>").appendTo("body").css({
    padding: "5px 7px",
    background: "#e9e9e9",
    position: "fixed",
    bottom: "15px",
    left: "35px"
});

//binds the "scroll" event
$(window).scroll(function (e) {
    var target = e.currentTarget,
        self = $(target),
        scrollTop = window.pageYOffset || target.scrollTop,
        lastScrollTop = self.data("lastScrollTop") || 0,
        scrollHeight = target.scrollHeight || document.body.scrollHeight,
        scrollText = "";

    if (scrollTop > lastScrollTop) {
        scrollText = "<b>scroll down</b>";
    } else {
        scrollText = "<b>scroll up</b>";
    }

    $("#test").html(scrollText +
      "<br>innerHeight: " + self.innerHeight() +
      "<br>scrollHeight: " + scrollHeight +
      "<br>scrollTop: " + scrollTop +
      "<br>lastScrollTop: " + lastScrollTop);

    if (scrollHeight - scrollTop === self.innerHeight()) {
      console.log("► End of scroll");
    }

    //saves the current scrollTop
    self.data("lastScrollTop", scrollTop);
});

Событие в колесе

Вы также можете взглянуть на MDN, в нем представлена ​​отличная информация о Событии в колесе .

Примечание: Событие колеса запускается только при использовании колесика мыши ;клавиши курсора и перетаскивание полосы прокрутки не запускают событие.

Я прочитал документ и пример: Прослушивание этого события через браузер
и после некоторых тестов с FF, IE, Chrome, Safari я получил следующий фрагмент:

//creates an element to print the scroll position
$("<p id='test'>").appendTo("body").css({
    padding: "5px 7px",
    background: "#e9e9e9",
    position: "fixed",
    bottom: "15px",
    left: "15px"
});

//attach the "wheel" event if it is supported, otherwise "mousewheel" event is used
$("html").on(("onwheel" in document.createElement("div") ? "wheel" : "mousewheel"), function (e) {
    var evt = e.originalEvent || e;

    //this is what really matters
    var deltaY = evt.deltaY || (-1 / 40 * evt.wheelDelta), //wheel || mousewheel
        scrollTop = $(this).scrollTop() || $("body").scrollTop(), //fix safari
        scrollText = "";

    if (deltaY > 0) {
        scrollText = "<b>scroll down</b>";
    } else {
        scrollText = "<b>scroll up</b>";
    }

    //console.log("Event: ", evt);
    $("#test").html(scrollText +
      "<br>clientHeight: " + this.clientHeight +
      "<br>scrollHeight: " + this.scrollHeight +
      "<br>scrollTop: " + scrollTop +
      "<br>deltaY: " + deltaY);
});
8 голосов
/ 12 января 2016

Если вы просто хотите узнать, прокручиваете ли вы вверх или вниз с помощью указателя (мыши или трекпада), вы можете использовать свойство deltaY события wheel.

$('.container').on('wheel', function(event) {
  if (event.originalEvent.deltaY > 0) {
    $('.result').append('Scrolled down!<br>');
  } else {
    $('.result').append('Scrolled up!<br>');
  }
});
.container {
  height: 200px;
  width: 400px;
  margin: 20px;
  border: 1px solid black;
  overflow-y: auto;
}
.content {
  height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
  <div class="content">
    Scroll me!
  </div>
</div>

<div class="result">
  <p>Action:</p>
</div>
3 голосов
/ 04 ноября 2014

Я видел много вариантов хороших ответов здесь, но, похоже, у некоторых людей возникают проблемы с кроссбраузерностью, так что это мое исправление.

Я успешно использовал это для определения направления в FF, IE и Chrome.Я не проверял его в сафари, так как обычно использую окна.

$("html, body").bind({'mousewheel DOMMouseScroll onmousewheel touchmove scroll': 
    function(e) {
        if (e.target.id == 'el') return;
        e.preventDefault();
        e.stopPropagation();

        //Determine Direction
        if (e.originalEvent.wheelDelta && e.originalEvent.wheelDelta >= 0) {
            //Up
            alert("up");

        } else if (e.originalEvent.detail && e.originalEvent.detail <= 0) {
            //Up
            alert("up");

        } else {
            //Down
            alert("down");
        }
    }
});

Имейте в виду, я также использую это, чтобы остановить прокрутку, поэтому, если вы хотите, чтобы прокрутка продолжалась, вы должны удалить e.preventDefault(); e.stopPropagation();

3 голосов
/ 29 января 2015

Чтобы игнорировать любой момент / импульс / отскок вверху и внизу страницы, вот модифицированная версия принятого Джозией ответа :

var prevScrollTop = 0;
$(window).scroll(function(event){

    var scrollTop = $(this).scrollTop();

    if ( scrollTop < 0 ) {
        scrollTop = 0;
    }
    if ( scrollTop > $('body').height() - $(window).height() ) {
        scrollTop = $('body').height() - $(window).height();
    }

    if (scrollTop >= prevScrollTop && scrollTop) {
        // scrolling down
    } else {
        // scrolling up
    }

    prevScrollTop = scrollTop;
});
3 голосов
/ 01 декабря 2010
var tempScrollTop, currentScrollTop = 0; 

$(window).scroll(function(){ 

   currentScrollTop = $("#div").scrollTop(); 

   if (tempScrollTop > currentScrollTop ) {
       // upscroll code
   }
  else if (tempScrollTop < currentScrollTop ){
      // downscroll code
  }

  tempScrollTop = currentScrollTop; 
} 

или используйте расширение колесика мыши , см. здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...