JQuery/JavaScript: определение направления прокрутки - проблема структуры кода
Мне нужно определить направление, в котором пользователь прокручивается - "вверх" или "вниз". На основе кода, найденного в этом ответе: Как определить направление события прокрутки jQuery?
Я попытался обернуть его в функцию, чтобы он немного отличался - но, к сожалению, он не работает. Я думаю, что это имеет какое-то отношение к тому, как я возвращаю значение, но направление всегда "вверх". Являясь довольно новым для JavaScript, у меня возникают проблемы с решением этой проблемы.
Вот код:
$(document).ready(function () {
'use strict';
var lastScrollTop = 0,
st,
direction;
function detectDirection() {
st = window.pageYOffset;
if (st > lastScrollTop) {
direction = "down";
} else {
direction = "up";
}
lastScrollTop = st;
return direction;
}
$(window).bind('scroll', function() {
detectDirection();
console.log(detectDirection());
});
});
И я также создал Fiddle.
Не могли бы вы помочь мне определить, где проблема?
Ответы
Ответ 1
$(window).bind('scroll', function() {
var dir = detectDirection();
console.log(dir);
});
Вы вызывали detectDirection()
дважды в течение каждого события прокрутки. Первый обнаружил правильное направление, но второй только увидел его в одном и том же месте, поэтому он вернул "вверх" и то, что вы зарегистрировали.
Ответ 2
Посмотрите, что у вас получилось:
if (st > lastScrollTop) {
direction = "down";
} else if (st < lastScrollTop ){
direction = "up";
} else {
direction = "static";
}
В дополнение к тому, что сказал Бармар, вы можете избавиться от линии (вызова) над выходом консоли и просто сохранить:
console.log(detectDirection());
Ответ 3
Код, поскольку он не будет работать, так как мы никогда не обновляем lastScrollTop, вот рабочий код...
$(function(config){
var lastScrollTop = 0, // setting initial scrolltop as top of page
direction; // direction of scroll 1)up -1)down 0)static
function detectDirection() {
// current scrollTop can't be cached or in the local global scope
var st = window.pageYOffset;
if (st > lastScrollTop) {
// scrolling down
direction = -1;
} else if (st < lastScrollTop ){
// scrolling up
direction = 1;
} else {
// static
direction = 0;
}
// updated lastscrolltop with new current top
lastScrollTop = st;
// return the direction
return direction;
}`
Я использовал 0 как статический /1 как прокрутку вверх /-1 как прокрутку вниз
Надеюсь, что это поможет кому-то.
Ответ 4
Я даю новый ответ, потому что, хотя ответ BarMar решает вашу непосредственную проблему, решение не поможет вам структурировать код таким образом, чтобы вы могли делать две вещи.
-
В широте охватить объект прокрутки, позволяя вам получить доступ к его атрибутам в другом месте. Это позволит вам что-то сделать, если позиция прокрутки является определенным значением.
-
Улучшите производительность прокрутки.
// Your current functionality
$(document).ready(function() {
var scroll = {
down: true,
pos: 0
};
var scrollPos;
var detectDirection = function() {
scrollPos = window.pageYOffset;
if (scrollPos > scroll.pos) {
scroll.down = true;
} else {
scroll.down = false;
}
scroll.pos = scrollPos;
};
$(window).on('optimizedScroll', function() {
detectDirection();
// Do something based on scroll direction
if (scroll.down == true) {
// fooFunction();
} else {
// barFunction();
}
// Do something based on scroll position,
// where scrollTrigger is a number
if (scroll.pos > scrollTrigger) {
// bazFunction();
}
});
});
// Improve scroll performance
(function() {
var throttle = function(type, name, obj) {
var obj = obj || window;
var running = false;
var func = function() {
if (running) {
return;
}
running = true;
requestAnimationFrame(function() {
obj.dispatchEvent(new CustomEvent(name));
running = false;
});
};
obj.addEventListener(type, func);
};
throttle('scroll', 'optimizedScroll');
})();
Вместо использования .bind(), вы должны использовать .on(), согласно jQuery.bind().
Немедленно вызывается функция выражения (IIFE) для улучшения производительности прокрутки происходит из Документация MDN для события прокрутки.