#javascript #jquery #scroll
#javascript #jquery #прокрутка
Вопрос:
Когда пользователь прокручивает прокручиваемый div (список) Я хочу, чтобы он прокручивал ровно 1 высоту элемента списка (22 пикселя). Проблема, с которой я сталкиваюсь, заключается в том, что если я обработаю событие $(element).scrolltop и выполню $(element).scrollTop(предыдущий scrollTop 22) внутри него, будет запущено новое событие «прокрутки», и мой обработчик будет вызван снова рекурсивно.
Пожалуйста, взгляните на этот пример: http://jsfiddle.net/VAFkk/1 /
Как я могу добиться прокрутки на определенное количество пикселей?
Как я могу изменить scrollTop без запуска события «прокрутки»?
Буду признателен за любые предложения. Используется jQuery 1.9.1.
JavaScript:
var previousScrollTop = $('.list').scrollTop();
// Bind scroll handler so that it scrolls exactly 22px.
$('.list').scroll(function() {
console.log('scroll happened');
var listElement = $(this);
var currentScrollTop = listElement.scrollTop();
if (currentScrollTop > previousScrollTop) {
listElement.scrollTop(previousScrollTop 22);
} else if (currentScrollTop < previousScrollTop) {
listElement.scrollTop(previousScrollTop - 22);
}
previousScrollTop = currentScrollTop;
});
HTML:
<div class="list">
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
<div class="list-item"></div>
</div>
CSS:
.list {
border: 1px solid red;
max-height: 88px;
overflow-y: auto;
}
.list-item {
border: 1px solid blue;
height: 20px;
}
Комментарии:
1. Установите флаг
ignorescroll
, deafultfalse
, если флагtrue
, установите егоfalse
и верните2. Не могли бы вы изменить jsFiddle? Насколько я вижу, это не работает. Если я вас правильно понял: jsfiddle.net/VAFkk/2
3. Что-то в этом роде, но все же не это … jsfiddle.net/VAFkk/3
4. Я думаю, я понял: jsfiddle.net/VAFkk/4 Спасибо.
5. Нет, все еще иногда ведет себя странно.
Ответ №1:
(function (step) { // capture variables so you don't pollute
var prev = $('.list').scrollTop(),
ignore_scroll = false; // flag
// declare what we want to do
function scroll_function(e) {
var me, cur;
// if flag true, don't do anything more
if (ignore_scroll) return;
// get vars after check (saves needless calls)
me = $(this),
cur = me.scrollTop();
// set flag
ignore_scroll = true;
// do stuff
if (cur > prev) me.scrollTop(prev = step);
else if (cur < prev) me.scrollTop(prev -= step);
// unset flag
ignore_scroll = false;
/* optional bonus, fix odd ends
prev = prev - (prev % step)
*/
}
// add handler
$('.list').scroll(scroll_function);
}(22)); // invoke
Комментарии:
1. Вау, большое вам спасибо. Дополнительная благодарность за комментарии. Лучший ответ, который я получил за долгое время. Отлично работает в Chrome и IE 10. На случай, если кому-то это нужно, вот jsfiddle: jsfiddle.net/Fwt68/1