views:

51

answers:

2

Hi,

I'm trying to create a looping animation that starts on onmousedown and stops on onmouseout. The effect is a simple scroll that will continue looping until you release the mouse.

I've created a function which performs the .animate method and it passes itself as a callback but the code only runs once.

Here's the entire code:

$(document).ready(function() {
var $scroller = $("#scroller");
var $content = $("#content", $scroller);

// lineHeight equal to 1 line of text
var lineHeight = $content.css('line-height');

//Amount to scroll = 3 lines of text a time
var amountToScroll = lineHeight.replace("px","")*3;
var maxScroll = $content.height() - $scroller.height();

function scrollDown() {
    var topCoord = $content.css("top").replace("px","");
    if(topCoord > -maxScroll) {
        if((-maxScroll-topCoord) > -amountToScroll) {
            $content.stop().animate({
                top: -maxScroll
            }, 1000
            );
        }
        else {
            $content.stop().animate({
                top: "-=" + amountToScroll
            }, 1000,
            function(){
                scrollDown()
            }
            );
        }
    }
}

function scrollUp() {
    var topCoord = $content.css("top").replace("px","");
    if(topCoord < 0) {
        if(topCoord > -amountToScroll) {
            $content.stop().animate({
                top: 0
            }, 1000
            );
        }
        else {
            $content.stop().animate({
                top: "+=" + amountToScroll
            }, 1000,
            function(){scrollUp()}
            );
        }
    }
}

$("#scroll-down").mousedown(function() {
    scrollDown();
});

$("#scroll-down").mouseup(function() {
    $content.stop();
});

$("#scroll-up").mousedown(function() {
    scrollUp();
});
$("scroll-up").mouseup(function() {
    $content.stop();
});
});
A: 

Have you tried removing the stop() calls?

function scrollDown() {
    var topCoord = parseInt($content.css("top").replace("px",""));
    if(topCoord > -maxScroll) {
        if((-maxScroll-topCoord) > -amountToScroll) {
            $content.animate({
                top: -maxScroll
            }, 1000
            );
        }
        else {
            $content.animate({
                top: "-=" + amountToScroll
            }, 1000, scrollDown
            );
        }
    }
}

You don't need the stop because the animation is always queued only after the current animation has ended.

Also, after it reaches the bottom, is it supposed to scroll back up then down again?

sirhc
Thanks @sirhc - it was the stop() that was interfering. Although I want to keep scrolling while the mouse is pressed, I don't want to build up a queue if someone clicks the button multiple times. Is there a way around this?
Marko
Take a look at the documentation for [`.stop()`](http://api.jquery.com/stop/) . An example is given. You may need to use `stop(true, true)`.However, because you're looping the animation, you can't use it right before animate or it will recur infinitely. You can use it at the `mouseup` though.
sirhc
+1  A: 

When you say "scroll" are you talking about the actual scroll position of an element with a scrollbar (as in the one that is likely on the right side of this page right now)?

If that's what you mean, jQuery has a scrollTop() method that can be used to get and set the scroll position.

var topCoord = $content.scrollTop();

...

$content.animate({
            scrollTop: "+=" + amountToScroll
        }, 1000,
        function(){scrollUp()}
        );

This will move the scrollbar position of the content.

Not sure if this is what you're trying to do, or if it is more of a slider where the scroller clips the content without a scrollbar, so you need to actually move the top coordinates of the content..

patrick dw