views:

144

answers:

1

I have a block of code that scrolls the page up via a animate jQuery thing, but to increase usability, if the user disturbs the scrolling motion in any way (e.g. scrolling wheel, grabbing the scrollbar, etc.) then it will immediately stop the motion.

I asked a question on this a week ago here but after some testers kindly tried out the code they reported that it did not work in Gecko-based browsers.

This is the code I have so far:

$(document).ready(function() {
    // scroll to top: check if user / animate is scrolling
    var scrollAnimating = false;

    jQuery.fx.step.scrollTop = function(E) {
        scrollAnimating = true;
        E.elem.scrollTop = E.now;
        scrollAnimating = false;
    };

    // go to top (on click)
    $('#gototop').click(function() {
        $(this).fadeOut(100,function() {
            $(this).css({backgroundColor: '#CCC'}).html('Going... (scroll to stop)').fadeIn(100, function() {
                $('html,body').animate({scrollTop:0},3000);
            })
        });

        $(window).scroll(function() {
            if (!scrollAnimating) {
                $('html,body').stop();
                $('#gototop').html('Go to top');
            };
        });

        resetNames();

        return false;
    });

    function resetNames() {
        setTimeout(function() {
            $('#gototop').html('Go to top').css({backgroundColor: '#DDD'});
        },3000);
    }
});

Basically on clicking #gototop it will start to animate the scroll to the top. If the scroll is disturbed the scrolling motion stops and the text for #gototop is reset.

There are a few problems with this code: some parts are ridiculously inefficient and it doesn't work in Gecko-based browsers (a biggie).

How do I get it to work? Any pointers on how to make it efficient?

A: 

Try simply $('body') selector for Gecko, also you will probably find that your animations mess up in Opera too because both html and body selectors are usable and the operation is performed twice. Try something like this (small test case):

    <html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;
        <script type="text/javascript">
            function scrollWin()
            {
                $('body').animate({scrollTop: $('html').offset().top}, 2000);
            }

            function scrollStop()
            {
                $('body').stop();
            }
        </script>
    </head>
    <body onkeyup="scrollStop()">
        <div style="background:grey;height:1500px"></div>
        <input type="button" onclick="scrollWin();" value="Scroll up" />
    </body>
</html>

The only thing with this is if you press something like enter or space, you will stop the animation but restart it again as you still have the button selected, so any other key will work or you can click on the document (off the button) and then use the enter or spacebar... basically the onkeyup was just another event to show you that the $('body').stop() is what you are really after.

Ambrosia
I need to have it to work in all browsers (with the exception of IE: if it doesn't work there, fine with me). Perhaps I should try some kind of browser-detecting script?
Brandon Wang
Did you try my script in your browsers? What was the result?
Ambrosia
There was no need to, because you completely missed the point of all the complex information (no offense intended): all the code is supposed to automatically stop the scrolling when it detects the user is trying to counter the scrolling (say, to stop it to read). it is obvious that your code does not do this. Sorry.
Brandon Wang
Sorry, yes, I posted that code to help with your Gecko problem but also because I found other people saying they had problems with similar selectors in Opera. All you need is the code in my next answer as well...
Ambrosia
Ok, just edited my last answer instead
Ambrosia