Estou procurando algo nesse sentido:
$(window).scroll(function(event){
if (/* magic code*/ ){
// upscroll code
} else {
// downscroll code
}
});
Alguma ideia?
wheel
evento atualmente: stackoverflow.com/a/33334461/3168107 .
Estou procurando algo nesse sentido:
$(window).scroll(function(event){
if (/* magic code*/ ){
// upscroll code
} else {
// downscroll code
}
});
Alguma ideia?
wheel
evento atualmente: stackoverflow.com/a/33334461/3168107 .
Respostas:
Verificar atual scrollTop
x anteriorscrollTop
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
// downscroll code
} else {
// upscroll code
}
lastScrollTop = st;
});
lastScrollTop
em 0 ou será inicializado corretamente?
var lastScrollTop = $(window).scrollTop()
após o navegador atualizar a posição de rolagem no carregamento da página.
Você pode fazer isso sem ter que acompanhar a parte superior da rolagem anterior, pois todos os outros exemplos exigem:
$(window).bind('mousewheel', function(event) {
if (event.originalEvent.wheelDelta >= 0) {
console.log('Scroll up');
}
else {
console.log('Scroll down');
}
});
Como não sou especialista nisso, sinta-se à vontade para pesquisar mais, mas parece que, quando você usa $(element).scroll
, o evento que está sendo ouvido é um evento de 'rolagem'.
Mas se você ouvir especificamente um mousewheel
evento usando bind, o originalEvent
atributo do parâmetro de evento no seu retorno de chamada conterá informações diferentes. Parte dessa informação é wheelDelta
. Se for positivo, você moveu a roda do mouse para cima. Se for negativo, você moveu o botão do mouse para baixo.
Meu palpite é que os mousewheel
eventos serão acionados quando a roda do mouse virar, mesmo que a página não role; um caso em que os eventos de 'rolagem' provavelmente não são acionados. Se desejar, você pode ligar event.preventDefault()
na parte inferior do seu retorno de chamada para impedir a rolagem da página e usar o evento roda do mouse para algo diferente de uma rolagem da página, como algum tipo de funcionalidade de zoom.
scrollTop
não foi atualizada. De fato, $(window).scroll()
não disparou nada.
Armazene o local de rolagem anterior e verifique se o novo é maior ou menor que isso.
Aqui está uma maneira de evitar qualquer variável global ( violino disponível aqui ):
(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
Poderia haver 3 soluções desta postagem e outras respostas .
Solução 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;
});
Solução 2
$('body').on('DOMMouseScroll', function(e){
if(e.originalEvent.detail < 0) {
console.log('up 2');
}
else {
console.log('down 2');
}
});
Solução 3
$('body').on('mousewheel', function(e){
if(e.originalEvent.wheelDelta > 0) {
console.log('up 3');
}
else {
console.log('down 3');
}
});
Não pude testá-lo no Safari
chrome 42 (vitória 7)
Firefox 37 (versão 7)
IE 11 (Vitória 8)
IE 10 (vitória 7)
IE 9 (vitória 7)
IE 8 (vitória 7)
Eu verifiquei que o efeito colateral do IE 11 e IE 8 é proveniente da
if else
declaração. Então, substituí-o com aif else if
seguinte declaração.
No teste de vários navegadores, decidi usar a Solução 3 para navegadores comuns e a Solução 1 para o Firefox e o IE 11.
Eu indiquei esta resposta para detectar o 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');
}
});
}
Safari browser
, seria útil complementar a solução.
Entendo que já houve uma resposta aceita, mas queria postar o que estou usando, caso isso possa ajudar alguém. Eu recebo a direção como cliphex
no evento mousewheel, mas com suporte ao Firefox. É útil fazê-lo dessa maneira, caso esteja fazendo algo como bloquear a rolagem e não conseguir obter o topo da rolagem atual.
Veja uma versão ao vivo aqui .
$(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
}
});
O evento de rolagem se comporta de maneira estranha no FF (é disparado várias vezes devido à rolagem de suavidade), mas funciona.
Nota: O evento de rolagem é acionado ao arrastar a barra de rolagem, usando as teclas do cursor ou a roda do mouse.
//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);
});
Você também pode dar uma olhada no MDN, que expõe ótimas informações sobre o evento Wheel .
Nota: O evento wheel é acionado apenas ao usar o mousewheel ; teclas do cursor e arrastar a barra de rolagem não acionam o evento.
Li o documento e o exemplo: Ouvindo esse evento no navegador
e depois de alguns testes com FF, IE, chrome, safari, acabei com este trecho:
//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);
});
Caso você queira apenas saber se você rola para cima ou para baixo usando um dispositivo apontador (mouse ou track pad), pode usar a propriedade deltaY do wheel
evento.
$('.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>
var tempScrollTop, currentScrollTop = 0;
$(window).scroll(function(){
currentScrollTop = $("#div").scrollTop();
if (tempScrollTop > currentScrollTop ) {
// upscroll code
}
else if (tempScrollTop < currentScrollTop ){
// downscroll code
}
tempScrollTop = currentScrollTop;
}
Eu já vi muitas versões de boas respostas aqui, mas parece que algumas pessoas estão tendo problemas entre navegadores, então essa é a minha correção.
Eu usei isso com sucesso para detectar a direção no FF, IE e Chrome ... Não testei no safari, pois normalmente uso o Windows.
$("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");
}
}
});
Lembre-se de que eu também uso isso para interromper a rolagem. Portanto, se você deseja que a rolagem ainda ocorra, remova o e.preventDefault(); e.stopPropagation();
Para ignorar qualquer pressão / momento / retorno na parte superior e inferior da página, aqui está uma versão modificada da resposta aceita de Josiah :
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;
});
Você pode determinar a direção do mousewhell.
$(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');
}
});
Use isso para encontrar a direção da rolagem. Isso é apenas para encontrar a direção do Rolagem Vertical. Suporta todos os navegadores cruzados.
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");
}
}
este código funciona bem com o IE, Firefox, Opera e Chrome:
$(window).bind('wheel mousewheel', function(event) {
if (event.originalEvent.deltaY >= 0) {
console.log('Scroll down');
}
else {
console.log('Scroll up');
}
});
'wheel mousewheel' e a propriedade deltaY devem ser usadas na função bind () .
Lembre-se: seu usuário deve atualizar o sistema e os navegadores por motivos de segurança. Em 2018, as desculpas de "Eu tenho o IE 7" são um absurdo. Nós devemos educar os usuários.
Tenha um bom dia :)
Mantenha super simples:
Caminho do jQuery Event Listener:
$(window).on('wheel', function(){
whichDirection(event);
});
Maneira de ouvinte de evento do Vanilla JavaScript:
if(window.addEventListener){
addEventListener('wheel', whichDirection, false);
} else if (window.attachEvent) {
attachEvent('wheel', whichDirection, false);
}
A função permanece a mesma:
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);
}
}
Eu escrevi um post mais aprofundada sobre ele aqui
Você pode usar as opções de rolagem e roda do mouse para rastrear o movimento para cima e para baixo ao mesmo tempo.
$('body').bind('scroll mousewheel', function(event) {
if (event.originalEvent.wheelDelta >= 0) {
console.log('moving down');
}
else {
console.log('moving up');
}
});
Você pode substituir 'corpo' por (janela) também.
Por que ninguém usa o event
objeto retornado pelo jQuery
scroll?
$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();
});
Estou usando chromium
e não verifiquei em outros navegadores se eles têm a dir
propriedade.
Como bind
foi preterido na v3 ("substituído por on
") e wheel
agora é suportado , esqueça wheelDelta
:
$(window).on('wheel', function(e) {
if (e.originalEvent.deltaY > 0) {
console.log('down');
} else {
console.log('up');
}
if (e.originalEvent.deltaX > 0) {
console.log('right');
} else {
console.log('left');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 style="white-space:nowrap;overflow:scroll">
🚂🚃🚃🚂🚃🚃🚃🚂🚃🚃🚂🚃🚃🚃🚂🚃<br/>
🚎🚌🚌🚌🚎🚌🚌🚎🚌🚌🚌🚎🚌🚌🚎🚌<br/>
🚂🚃🚃🚂🚃🚃🚃🚂🚃🚃🚂🚃🚃🚃🚂🚃<br/>
🚎🚌🚌🚌🚎🚌🚌🚎🚌🚌🚌🚎🚌🚌🚎🚌<br/>
🚂🚃🚃🚂🚃🚃🚃🚂🚃🚃🚂🚃🚃🚃🚂🚃<br/>
🚎🚌🚌🚌🚎🚌🚌🚎🚌🚌🚌🚎🚌🚌🚎🚌<br/>
</h1>
wheel
Compatibilidade do navegador do evento nos MDNs (2019-03-18) :
if(e.originalEvent.deltaY > 0) { console.log('down'); } else if(e.originalEvent.deltaY < 0) { console.log('up'); } else if(e.originalEvent.deltaX > 0) { console.log('right'); } else if(e.originalEvent.deltaX < 0) { console.log('left'); }
Você pode usar isso também
$(document).ready(function(){
var currentscroll_position = $(window).scrollTop();
$(window).on('scroll', function(){
Get_page_scroll_direction();
});
function Get_page_scroll_direction(){
var running_scroll_position = $(window).scrollTop();
if(running_scroll_position > currentscroll_position) {
$('.direction_value').text('Scrolling Down Scripts');
} else {
$('.direction_value').text('Scrolling Up Scripts');
}
currentscroll_position = running_scroll_position;
}
});
.direction_value{
position: fixed;
height: 30px;
background-color: #333;
color: #fff;
text-align: center;
z-index: 99;
left: 0;
top: 0;
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="direction_value">
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi ducimus expedita facilis architecto fugiat veniam natus suscipit amet beatae atque, enim recusandae quos, magnam, perferendis accusamus cumque nemo modi unde!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi ducimus expedita facilis architecto fugiat veniam natus suscipit amet beatae atque, enim recusandae quos, magnam, perferendis accusamus cumque nemo modi unde!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi ducimus expedita facilis architecto fugiat veniam natus suscipit amet beatae atque, enim recusandae quos, magnam, perferendis accusamus cumque nemo modi unde!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi ducimus expedita facilis architecto fugiat veniam natus suscipit amet beatae atque, enim recusandae quos, magnam, perferendis accusamus cumque nemo modi unde!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi ducimus expedita facilis architecto fugiat veniam natus suscipit amet beatae atque, enim recusandae quos, magnam, perferendis accusamus cumque nemo modi unde!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi ducimus expedita facilis architecto fugiat veniam natus suscipit amet beatae atque, enim recusandae quos, magnam, perferendis accusamus cumque nemo modi unde!</p>
Esta é uma solução ideal para detectar a direção exatamente quando o usuário termina a rolagem.
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));
});
Você deve tentar isso
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();
});
Tive problemas com a rolagem elástica ( deslocamento da rolagem, bandas de borracha). Ignorar o evento de rolagem para baixo, se próximo ao topo da página, funcionou para mim.
var position = $(window).scrollTop();
$(window).scroll(function () {
var scroll = $(window).scrollTop();
var downScroll = scroll > position;
var closeToTop = -120 < scroll && scroll < 120;
if (downScroll && !closeToTop) {
// scrolled down and not to close to top (to avoid Ipad elastic scroll-problems)
$('.top-container').slideUp('fast');
$('.main-header').addClass('padding-top');
} else {
// scrolled up
$('.top-container').slideDown('fast');
$('.main-header').removeClass('padding-top');
}
position = scroll;
});
Isso funciona em todos os navegadores de PC ou telefone, expandindo as principais respostas. Pode-se construir uma janela de objeto de evento mais complexa ["scroll_evt"] e chamá-la na função handleScroll (). Este dispara para 2 condições simultâneas, se um certo atraso tiver passado ou um certo delta for passado para eliminar alguns disparos indesejados.
window["scroll_evt"]={"delta":0,"delay":0,"direction":0,"time":Date.now(),"pos":$(window).scrollTop(),"min_delta":120,"min_delay":10};
$(window).scroll(function() {
var currentScroll = $(this).scrollTop();
var currentTime = Date.now();
var boolRun=(window["scroll_evt"]["min_delay"]>0)?(Math.abs(currentTime - window["scroll_evt"]["time"])>window["scroll_evt"]["min_delay"]):false;
boolRun = boolRun && ((window["scroll_evt"]["min_delta"]>0)?(Math.abs(currentScroll - window["scroll_evt"]["pos"])>window["scroll_evt"]["min_delta"]):false);
if(boolRun){
window["scroll_evt"]["delta"] = currentScroll - window["scroll_evt"]["pos"];
window["scroll_evt"]["direction"] = window["scroll_evt"]["delta"]>0?'down':'up';
window["scroll_evt"]["delay"] =currentTime - window["scroll_evt"]["time"];//in milisecs!!!
window["scroll_evt"]["pos"] = currentScroll;
window["scroll_evt"]["time"] = currentTime;
handleScroll();
}
});
function handleScroll(){
event.stopPropagation();
//alert(window["scroll_evt"]["direction"]);
console.log(window["scroll_evt"]);
}