Sir
Sir

Reputation: 8280

Javascript scroll function

I made my own scroll function in javascript using an event listener with the mouse wheel, the problem is, the function allows the user to keep scrolling down roughly to far rather than stop once they have reached the bottom of the scrolling div..

This is what i have: http://jsfiddle.net/RjEr7/7/

The function in question:

function do_it(e){
    var jump = 50;
    var parentHeight = parseInt(this.parentNode.offsetHeight)-50;
    var childHeight = parseInt(this.offsetHeight);
    var i = parseInt(this.style.marginTop, 10) || 0;
    var wheel = e.wheelDeltaY;
    var childHeightNew = childHeight + i;

    if(wheel == -120){
        if(childHeightNew > parentHeight){                                                  
                i -= jump;  
        }
    }else if(wheel == 120){
        if( (childHeightNew < childHeight) && i < 0){
                i += jump;
            if(i>0){
                    i=0;
            }
        }
    }
this.style.marginTop = i + 'px';
}

In the JSfiddle, you will see the red box scrolls up too far. Not sure how to fix it though.

Please help.

Upvotes: 5

Views: 2386

Answers (2)

Shylo Hana
Shylo Hana

Reputation: 1870

You may want to try this. I have no idea if it works in anything other than Firefox though:

function do_it(e) {
  if(!e) {
    var e = window.event;
  }

  var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));

  switch(delta) {
    case 1:
      e.currentTarget.scrollTop -= 50;
      break;

    case -1:
      e.currentTarget.scrollTop += 50;
      break;
  }
}

Upvotes: 0

ndm
ndm

Reputation: 60463

Try this, it should be pretty much self explantory:

function do_it(e) {
    var skip = 50;

    var parentHeight = parseInt(this.parentNode.clientHeight);
    var childHeight = parseInt(this.offsetHeight);
    var canMove = childHeight - parentHeight;
    var distance = e.wheelDeltaY < 0 ? -skip : skip;

    var pos = parseInt(this.style.marginTop, 10) || 0;
    pos = Math.min(0, Math.max(-canMove, pos + distance));

    this.style.marginTop = pos + 'px';
}

document.getElementById('id').addEventListener('mousewheel',do_it,false);

Instead of all this if else stuff it clamps the position between -can move and 0. Also note the use of clientHeight instead of offsetHeight so that the parents border size is excluded!

The problem with your logic is that it doesn't incorporate the maximum distance the child is allowed to move in the top direction, it will jump in 50 pixel steps, and in case the newly calculated child height is smaller than the parent, it just stops, where it would also need to limit the margin to the maximum, similar to what you are already doing for the bottom direction (if(i > 0) i = 0). Additionally you are substracting 50 pixel from the parent height (for whatever reason?) which will make the overshoot even bigger.

Upvotes: 2

Related Questions