5

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.

8
  • It looks like the event listener isn't wired right. Add alert('egewrweg'); at the beginning of the function -for me, there was no alert message when I scrolled. Commented Jul 1, 2013 at 1:45
  • @frenchie jsfiddle.net/RjEr7/8 alert works fine. Commented Jul 1, 2013 at 1:46
  • jsfiddle.net/RjEr7/9 this works; not sure why but even the fiddle you just updated doesn't trigger the alert. Use the jquery scroll handler to debug so that at least we're sure the handler works. Commented Jul 1, 2013 at 1:49
  • Then maybe your browser blocked the alerts but your fiddle does nothing... Commented Jul 1, 2013 at 1:50
  • My fiddle does nothing because I commented out the line that has the alert so we could debug the function. Commented Jul 1, 2013 at 1:51

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Sorry, it was very late yesterday, I've added a short explanation of what's wrong with your logic.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.