Aremyst
Aremyst

Reputation: 1528

Scroll div for certain amount of pixels: how to scroll div without causing scroll event

When user scrolls scrollable div(list) I want it to scroll exactly 1 height of the list-item(22px). The problem I have is that if I handle $(element).scroll event and execute $(element).scrollTop(previousScrollTop + 22) inside of it, new "scroll" event will be fired and my handler will be called again recursively.

Please take a look at this example: http://jsfiddle.net/VAFkk/1/

How can I achieve scrolling for certain amount of pixels?
How can I change the scrollTop without firing the "scroll" event ?

Would appreciate any suggestions. JQuery 1.9.1 is used.

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;
}

Upvotes: 0

Views: 2094

Answers (1)

Paul S.
Paul S.

Reputation: 66334

(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

Upvotes: 2

Related Questions