Search code examples
jqueryhtmlcss

How can I make a scrollbar only scroll at fixed intervals?


I have a container div with fixed size and overflow: scroll, it's filled with smaller divs making a sort of list. here is a fiddle example: http://jsfiddle.net/etYSC/2/

what I want is that the scrolling never cuts a box, making always 3 full boxes showing (in this example), so it will scroll always a fixed number of pixels.

How do I do this?

I'm using jquery library.

Google has been a harsh mistress on this question because of the misleading keywords.

-- solution

I was able to refine kiranvj code a bit more and I am very pleased with the final result.

snapping the the previous div:

var scrollTimerHandle = "";
var positionTimerHandle = "";

$("#container").scroll(function() {
    var boxSize = 84;   
    var newScrollPosition = parseInt(this.scrollTop / boxSize) * boxSize,
    _this = this;

    clearInterval(scrollTimerHandle);  
    scrollTimerHandle  = setTimeout(function() {
        positionTimerHandle = setInterval(function(){
          if (_this.scrollTop == newScrollPosition){
             clearInterval(positionTimerHandle);                   
          } else {
             _this.scrollTop--;
          }
        }, 5);         

    }, 600);   
});

http://jsfiddle.net/etYSC/7/

snapping to the closest div

var scrollTimerHandle = "";
var positionTimerHandle = "";

$("#container").scroll(function() {
var boxSize = 84;    
var preScrollPosition = parseInt(this.scrollTop / boxSize) * boxSize;
var newScrollPosition = this.scrollTop - preScrollPosition < boxSize /2 
                             ? preScrollPosition : preScrollPosition + boxSize;
_this = this;

clearInterval(scrollTimerHandle);

    scrollTimerHandle  = setTimeout(function() {
        positionTimerHandle = setInterval(function(){      
          if (_this.scrollTop == newScrollPosition){
            clearInterval(positionTimerHandle);
          } else {
              if (_this.scrollTop > newScrollPosition){
                _this.scrollTop--;
              } else {
                _this.scrollTop++;  
              }          
          }
        }, 5);     

    }, 700);
});

http://jsfiddle.net/etYSC/8/

Thanks for all the help, I was lost on how to aproach this and learned a good deal today.


Solution

  • Not a perfect solution.

    But something like this should work (NB : need to refine)

    ​$("#container").scroll(function() {
    
       this.scrollTop = parseInt(this.scrollTop / 84) * 84; // 84 = height + top and bottom margin
    
    });​​​
    

    Fiddle here http://jsfiddle.net/R7tAK/1/

    Update

    Some what refined code than the above, without any other plugins or libs. (flicker removed)

    var scrollTimerHandle = "";
    
    $("#container").scroll(function() {
    
    var newScrollPosition = parseInt(this.scrollTop / 84) * 84,
        _this = this;
    
        clearInterval(scrollTimerHandle);
    
    scrollTimerHandle  = setTimeout(function() {
       _this.scrollTop = newScrollPosition ;
    
    }, 1000);
    
    
    });​ 
    

    Play here http://jsfiddle.net/R7tAK/4/