Comment puis-je déterminer la direction d'un événement jQuery scroll?
je cherche quelque chose à cet effet:
$(window).scroll(function(event){
if (/* magic code*/ ){
// upscroll code
} else {
// downscroll code
}
});
des idées?
22 réponses
non-fumeurs scrollTop
vs précédent scrollTop
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
// downscroll code
} else {
// upscroll code
}
lastScrollTop = st;
});
vous pouvez le faire sans avoir à garder la trace du parchemin précédent, comme tous les autres exemples l'exigent:
$(window).bind('mousewheel', function(event) {
if (event.originalEvent.wheelDelta >= 0) {
console.log('Scroll up');
}
else {
console.log('Scroll down');
}
});
je ne suis pas un expert sur ce n'hésitez donc pas à approfondir les recherches, mais il semble que lorsque vous utilisez $(element).scroll
, l'événement d'être écouté, pour un défilement de l'événement.
mais si vous écoutez spécifiquement un événement mousewheel
en utilisant bind, l'attribut originalEvent
du paramètre d'événement à votre callback contient des informations différentes. Une partie de cette information est wheelDelta
. Si c'est positif, tu as remué la roue. Si c'est négatif, vous avez baissé le volant.
à mon avis, les événements mousewheel
se déclenchent lorsque la roue de la souris tourne, même si la page ne défile pas; un cas dans lequel les événements "scroll" ne se déclenchent probablement pas. Si vous voulez, vous pouvez appeler event.preventDefault()
au bas de votre rappel pour empêcher la page de défiler, et pour que vous puissiez utilisez l'événement mousewheel pour autre chose qu'un défilement de page, comme une fonctionnalité de zoom.
stockez l'emplacement de défilement précédent, puis voyez si le nouveau est plus grand ou moins que cela.
voici un moyen d'éviter toute variable globale ( fiddle disponible ici ):
(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
Solution
Il pourrait y avoir 3 solution à partir de ce message et de autre réponse .
Solution 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;
});
Solution 2
$('body').on('DOMMouseScroll', function(e){
if(e.originalEvent.detail < 0) {
console.log('up 2');
}
else {
console.log('down 2');
}
});
Solution 3
$('body').on('mousewheel', function(e){
if(e.originalEvent.wheelDelta > 0) {
console.log('up 3');
}
else {
console.log('down 3');
}
});
Multi Browser Test
Je n'ai pas pu le tester sur Safari
chrome 42 (Win 7)
- Solution 1
- : 1 cas pour 1 scroll
- vers le bas: 1 événement pour 1 rouleau
- Soltion 2
- : Pas de travail
- vers le Bas : Pas de travail
- Solution 3
- : 1 cas pour 1 scroll
- vers le bas: 1 événement pour 1 rouleau
Firefox 37 (Win 7)
- Solution 1
- : 20 événements par 1 scroll
- vers le Bas : 20 événements par 1 scroll
- Soltion 2
- Up : Ne fonctionne pas
- vers le bas: 1 événement pour 1 rouleau
- Solution 3
- : Pas de travail
- vers le Bas : Pas de travail
IE 11 (Win 8)
- Solution 1
- : 10 événements par 1 rouleau (effet secondaire : défilement s'est produit à la dernière)
- En bas: 10 événements pour 1 rouleau
- Soltion 2
- : Pas de travail
- vers le Bas : Pas de travail
- Solution 3
- : Pas de travail
- vers le bas: 1 événement pour 1 rouleau
IE 10 (Win 7)
- Solution Un
- : 1 cas pour 1 scroll
- vers le bas: 1 événement pour 1 rouleau
- Soltion 2
- : Pas de travail
- vers le Bas : Pas de travail
- Solution 3
- : 1 cas pour 1 scroll
- vers le bas: 1 événement pour 1 rouleau
IE 9 (Win 7)
- Solution 1
- : 1 cas pour 1 scroll
- vers le bas: 1 événement pour 1 rouleau
- Soltion 2
- : Pas de travail
- vers le Bas : Pas de travail
- Solution 3
- Up : 1 événement pour 1 rouleau
- vers le bas: 1 événement pour 1 rouleau
IE 8 (Win 7)
- Solution 1
- : 2 événements par 1 rouleau (effet secondaire : défilement s'est produit à la dernière)
- vers le Bas : 2~4 événements par 1 scroll
- Soltion 2
- : Pas de travail
- vers le Bas : Pas de travail
- Solution 3
- : 1 cas pour 1 scroll
- vers le bas: 1 événement pour 1 rouleau
Solution Combinée
j'ai vérifié que les effets secondaires de IE 11 et IE 8 proviennent de l'énoncé
if else
. Donc, je l'ai remplacé parif else if
déclaration suivant.
du test multi-navigateurs, j'ai décidé d'utiliser Solution 3 pour les navigateurs courants et Solution 1 pour firefox et IE 11.
j'ai appelé cette réponse pour détecter 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.);
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');
}
});
}
je comprends qu'il y a déjà eu une réponse acceptée, mais j'ai voulu poster ce que j'utilise au cas où il pourrait aider n'importe qui. Je reçois la direction comme cliphex
avec l'événement mousewheel mais avec le soutien pour Firefox. Il est utile de le faire de cette façon au cas où vous faites quelque chose comme verrouiller scroll et ne pouvez pas obtenir le haut de scroll actuel.
voir une version live ici .
$(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
}
});
Événement De Défilement
le scroll event se comporte étrangement en FF (il est tiré beaucoup de fois en raison de la douceur de défilement) mais il fonctionne.
Note: le scroll event actually est tiré en faisant glisser la barre de défilement, en utilisant les touches de curseur ou mousewheel.
//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);
});
La Roue De L'Événement
vous pouvez également jeter un oeil à MDN, il expose une grande information sur le événement de roue .
Note: l'événement de la roue n'est déclenché qu'en utilisant le volant ; les touches du curseur et le déplacement de la barre de défilement ne déclenchent pas l'événement.
j'ai lu le document et l'exemple: écouter cet événement à travers le navigateur
et après quelques tests avec FF, IE, chrome, safari, j'ai fini avec ce snippet:
//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);
});
dans le cas où vous voulez juste savoir si vous faites défiler vers le haut ou vers le bas en utilisant un dispositif de pointeur (souris ou track pad), vous pouvez utiliser la propriété deltaY de l'événement 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>
var tempScrollTop, currentScrollTop = 0;
$(window).scroll(function(){
currentScrollTop = $("#div").scrollTop();
if (tempScrollTop > currentScrollTop ) {
// upscroll code
}
else if (tempScrollTop < currentScrollTop ){
// downscroll code
}
tempScrollTop = currentScrollTop;
}
ou utilisez la extension de la mouse , voir ici .
pour ignorer tout snap / momentum / rebondir en haut et en bas de la page, voici une version modifiée de réponse acceptée 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;
});
vous pouvez déterminer la direction de 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');
}
});
j'ai vu beaucoup de versions de bonnes réponses ici, mais il semble que certaines personnes ont des problèmes de navigateur croisé donc ceci est ma solution.
Je l'ai utilisé avec succès pour détecter la direction en FF, IE et Chrome ... Je ne l'ai pas testé en safari car j'utilise windows en général.
$("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");
}
}
});
gardez à l'esprit que je l'utilise aussi pour arrêter tout défilement donc si vous voulez que le défilement se produit encore, vous devez supprimer le e.preventDefault(); e.stopPropagation();
utilisez ceci pour trouver la direction du rouleau. Ceci est seulement pour trouver la direction du rouleau Vertical. Prend en charge tous les navigateurs.
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");
}
}
stock un incrément dans le .data ()
de l'élément laminé, vous serez alors en mesure de tester le nombre de fois que le rouleau atteint en haut.
Keep it simple:
jQuery Écouteur d'Événement:
$(window).on('wheel', function(){
whichDirection(event);
});
Vanille JavaScript Écouteur D'Événement:
if(window.addEventListener){
addEventListener('wheel', whichDirection, false);
} else if (window.attachEvent) {
attachEvent('wheel', whichDirection, false);
}
La Fonction Reste La Même:
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);
}
}
j'ai écrit un post plus approfondi sur elle ici
vous pouvez utiliser les deux options scroll et mousewheel pour suivre les mouvements à la fois.
$('body').bind('scroll mousewheel', function(event) {
if (event.originalEvent.wheelDelta >= 0) {
console.log('moving down');
}
else {
console.log('moving up');
}
});
vous pouvez aussi remplacer "body" par (window).
ce code fonctionne très bien avec IE, Firefox, Opera et Chrome:
$(window).bind('wheel mousewheel', function(event) {
if (event.originalEvent.deltaY >= 0) {
console.log('Scroll up');
}
else {
console.log('Scroll down');
}
});
'roue de la roulette de la souris' et la propriété deltaY doit être utilisé en bind() de la fonction.
rappelez-vous : vous êtes l'utilisateur doit mettre à jour leur système et les navigateurs pour des raisons de sécurité. En 2018, Les excuses de "j'ai IE 7" est un non-sens. Nous devons éduquer les utilisateurs.
bonne journée :)
pour ceux qui ont des problèmes avec le défilement élastique, s'il vous plaît utiliser cette réponse
dans le .data()
de l'élément vous pouvez stocker un JSON et des valeurs de test pour lancer des événements
{ top : 1,
first_top_event: function(){ ...},
second_top_event: function(){ ...},
third_top_event: function(){ ...},
scroll_down_event1: function(){ ...},
scroll_down_event2: function(){ ...}
}
c'est une détection simple et facile pour quand l'utilisateur s'éloigne du haut de la page et pour quand ils reviennent au haut.
$(window).scroll(function() {
if($(window).scrollTop() > 0) {
// User has scrolled
} else {
// User at top of page
}
});
il s'agit d'une solution optimale pour détecter la direction juste lorsque l'Utilisateur termine le défilement.
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));
});
, Vous Devriez essayer ce
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();
});
Pourquoi personne ne l' event
objet retourné par jQuery
, faites défiler ?
$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();
});
j'utilise chromium
et je n'ai pas vérifié sur les autres navigateurs s'ils ont la propriété dir
.