Прокручивать div на определенное количество пикселей: как прокручивать div, не вызывая события прокрутки

#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 , deafult false , если флаг 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