Как я могу определить направление события прокрутки jQuery?

315

Я искал что-то с этим:

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

Любые идеи?

Теги:

25 ответов

597
Лучший ответ

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

var lastScrollTop = 0;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
       // downscroll code
   } else {
      // upscroll code
   }
   lastScrollTop = st;
});
  • 13
    Есть ли способ установить чувствительность к этому?
  • 7
    Я сделал пример на этом коде. Возможно, я обновлю этот ответ с помощью плагина jQuery из-за популярности.
Показать ещё 18 комментариев
160

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

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

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

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

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

  • 12
    Хорошо, но, к сожалению, единственный Firefox не поддерживает его developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/… (протестировано в FF v15). : C
  • 8
    Это было полезно для меня: мне нужно было обнаружить прокрутку, хотя сама страница на самом деле не прокручивалась, поэтому scrollTop не обновлялся. На самом деле, $(window).scroll() вообще не срабатывает.
Показать ещё 10 комментариев
28

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

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

(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
26

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

Из этого сообщения может быть 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
    • Вверх: 1 событие за 1 прокрутку
    • Вниз: 1 событие за 1 прокрутку
  • Soltion 2
    • Вверх: не работает
    • Вниз: не работает
  • Решение 3
    • Вверх: 1 событие за 1 прокрутку
    • Вниз: 1 событие за 1 прокрутку

Firefox 37 (Win 7)

  • Решение 1
    • Вверх: 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
    • Вверх: 1 событие за 1 прокрутку
    • Вниз: 1 событие за 1 прокрутку
  • Soltion 2
    • Вверх: не работает
    • Вниз: не работает
  • Решение 3
    • Вверх: 1 событие за 1 прокрутку
    • Вниз: 1 событие за 1 прокрутку

IE 9 (Win 7)

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

IE 8 (Win 7)

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

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

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

Из теста нескольких браузеров я решил использовать Решение 3 для обычных браузеров и Решение 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');
            }
        });
    }
  • 0
    Если кто-то может добавить результат Safari browser , было бы полезно дополнить решение.
  • 0
    К сожалению! Я обнаружил, что Mobile Chrome и Android-браузер по умолчанию охватываются только решением 1. Поэтому было бы лучше использовать оба решения 1 и 3, чтобы охватить различные браузеры.
Показать ещё 2 комментария
12

Я понимаю, что уже был принятый ответ, но мне хотелось опубликовать то, что я использую, если оно может помочь кому угодно. Я получаю направление как 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
    }
});
  • 0
    @EtienneMart в приведенном выше коде полагается на jQuery, если это и было причиной вашей ошибки. Пожалуйста, посмотрите прилагаемую скрипку, чтобы увидеть, как она работает.
8

Прокрутить событие

событие прокрутки ведет себя странно в 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, он предоставляет отличную информацию о Wheel Event.

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

Я прочитал документ и пример: Прослушивание этого события в браузере
и после некоторых тестов с 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);
});
  • 2
    У меня есть фиксированный вид панели, который отключает фактическую полосу прокрутки, поэтому мне нужно было определить направление от колеса мыши. Ваше решение для колесика мыши отлично работало в разных браузерах, так что спасибо вам за это!
  • 1
    Это должен быть принятый ответ.
7

Если вы просто хотите узнать, прокручиваете ли вы вверх или вниз с помощью указательного устройства (мыши или дорожки), вы можете использовать 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

Вы можете определить направление в мышеловке.

$(window).on('mousewheel DOMMouseScroll', function (e) {
    var delta = e.originalEvent.wheelDelta ? 
                   e.originalEvent.wheelDelta : -e.originalEvent.detail;

    if (delta >= 0) {
        console.log('scroll up');
    } else {
        console.log('scroll down');
    }
});
3

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

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

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

Я успешно использовал это для определения направления в 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();

  • 1
    всегда возвращается вниз на Android GS5
  • 0
    Это сработало отлично! У меня была проблема с лучшим ответом на вопрос IE. Это не та проблема! +1 от меня.
3
var tempScrollTop, currentScrollTop = 0; 

$(window).scroll(function(){ 

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

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

  tempScrollTop = currentScrollTop; 
} 

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

2

этот код прекрасно работает с IE, Firefox, Opera и Chrome:

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

'wheel mousewheel' и свойство deltaY должны использоваться в функции bind().

Помните: ваш пользователь должен обновить свою систему и браузеры из соображений безопасности. В 2018 году оправдание "у меня IE 7" - это чепуха. Мы должны обучать пользователей.

Хорошего дня :)

  • 0
    Я попробовал твой код, и это другой путь. Первый срабатывает при прокрутке вниз, а второй - при прокрутке вверх.
2

Используйте это, чтобы найти направление прокрутки. Это только для того, чтобы найти направление вертикальной прокрутки. Поддерживает все кросс-браузеры.

    var scrollableElement = document.getElementById('scrollableElement');

    scrollableElement.addEventListener('wheel', findScrollDirectionOtherBrowsers);

    function findScrollDirectionOtherBrowsers(event){
        var delta;

        if (event.wheelDelta){
            delta = event.wheelDelta;
        }else{
            delta = -1 * event.deltaY;
        }

        if (delta < 0){
            console.log("DOWN");
        }else if (delta > 0){
            console.log("UP");
        }

    }

Пример

2

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

 $('body').bind('scroll mousewheel', function(event) {

if (event.originalEvent.wheelDelta >= 0) {
      console.log('moving down');   
    }
    else {
      console.log('moving up'); 
    }
});

Вы также можете заменить "тело" на (окно).

  • 0
    Кажется, хорошо работает в Chrome, но не в FF (55.0.2, Ubuntu)
1

Почему никто не использует объект event возвращаемый jQuery при прокрутке?

$window.on('scroll', function (event) {
    console.group('Scroll');
    console.info('Scroll event:', event);
    console.info('Position:', this.pageYOffset);
    console.info('Direction:', event.originalEvent.dir); // Here is the direction
    console.groupEnd();
});

Я использую chromium и я не проверял в других браузерах, имеют ли они свойство dir.

1

Держите его супер простым:

jQuery Способ прослушивания событий:

$(window).on('wheel', function(){
  whichDirection(event);
});

Ванильный JavaScript-приемник событий:

if(window.addEventListener){
  addEventListener('wheel', whichDirection, false);
} else if (window.attachEvent) {
  attachEvent('wheel', whichDirection, false);
}

Функция Остается То же:

function whichDirection(event){
  console.log(event + ' WheelEvent has all kinds of good stuff to work with');
  var scrollDirection = event.deltaY;
  if(scrollDirection === 1){
    console.log('meet me at the club, going down', scrollDirection);
  } else if(scrollDirection === -1) {
    console.log('Going up, on a tuesday', scrollDirection);
  }
}

Я написал более indepth пост на нем здесь

  • 0
    Требуется ли колесо jquery для использования версии jquery?
  • 0
    Колесо jquery не требуется для этого @HastigZusammenstellen
1

укажите приращение элемента .data () прокрутки элемента, после чего вы сможете проверить количество раз, когда прокрутка достигла вершины.

0

Ни одно из этих решений, кажется, не работает для меня. Я попробовал это здесь; https://codepen.io/WebWanted/pen/exeMXX?editors=1111

 <p id="idOfUl"class="animated">Flip-out-X</p>

JS

    jQuery(window).scroll(function(event){
   var st = jQuery(this).scrollTop();
   if (st > lastScrollTop){
      jQuery(".animated").addClass("flipOutX");

   } 

   lastScrollTop = st;
});

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

@Cody Grey Почему вы удалили этот вопрос? Я думаю, что создание новых постов для этой темы противоречит правилам, не так ли? К сожалению, я не могу написать вам сообщение - иначе я бы сделал это, прежде чем оставить другой комментарий - и вы не написали бы мне тоже. Если вы думаете, что я сделал что-то не так, то вы ясно видите, что я новичок в этом форуме, поэтому вы можете сказать мне, что не так, вместо того, чтобы просто удалить мой вопрос. Это не цивилизованный способ взаимодействия друг с другом, и я не ценю такого поведения вообще.

Лучший, Крис

0

Ни одно из этих решений, кажется, не работает для меня.

https://codepen.io/WebWanted/pen/exeMXX?editors=1111

<p class="animated">Flip-out-X</p>
orem ipsum dolor sit amet, назначенный элитом. Энейский коммандос Лигула Эгет Долор. Эней Масса. Cum sociis natoque penatibus et
0

Вы должны попробовать это

var scrl
$(window).scroll(function(){
        if($(window).scrollTop() < scrl){
            //some code while previous scroll
        }else{
            if($(window).scrollTop() > 200){
                //scroll while downward
            }else{//scroll while downward after some specific height
            }
        }
        scrl = $(window).scrollTop();
    });
0

Это оптимальное решение для определения направления, когда прокрутка пользователя заканчивается.

var currentScrollTop = 0 ;

$(window).bind('scroll', function () {     

    scrollTop = $(this).scrollTop();

    clearTimeout($.data(this, 'scrollTimer'));
    $.data(this, 'scrollTimer', setTimeout(function() {

        if(scrollTop > currentScrollTop){
            // downscroll code
            $('.mfb-component--bl').addClass('mfbHide');
        }else{
            // upscroll code
            $('.mfb-component--bl').removeClass('mfbHide');
        }
        currentScrollTop = scrollTop;

    }, 250));

});
0

Это простое и простое обнаружение, когда пользователь прокручивается от верхней части страницы и когда возвращается в начало.

$(window).scroll(function() {
    if($(window).scrollTop() > 0) {
        // User has scrolled
    } else {
        // User at top of page
    }
});
0

это может помочь

<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
  <script type='text/javascript'>
    $(function(){
      //Keep track of last scroll
      var lastScroll = 0;
      $(window).scroll(function(event){
          //Sets the current scroll position
          var st = $(this).scrollTop();
          //Determines up-or-down scrolling
          if (st > lastScroll){
             //alert("DOWN");
            $('#bg').text('DOWN')
          } 
          else {
            //alert("UP");
            $('#bg').text('UP')
          }
          //Updates scroll position
          lastScroll = st;
      });
    });
  </script>
</head>
<body>
  <h1 id="bg">Scroll Here</h1>
</body>
</html>
0

в .data() элемента вы можете сохранить JSON и проверить значения для запуска событий

{ top : 1,
   first_top_event: function(){ ...},
   second_top_event: function(){ ...},
   third_top_event: function(){ ...},
   scroll_down_event1: function(){ ...},
   scroll_down_event2: function(){ ...}
}
0

Для тех, у кого проблемы с эластичной прокруткой, используйте этот ответ

Как определить направление прокрутки

Ещё вопросы

Сообщество Overcoder
Наверх
Меню