views:

117

answers:

2

I currently have a scrolling anchor animation that also adds an "active" class to the anchor clicked. I am trying to fit the below function into the works as well, so say someone clicks "anchor 1", "anchor 1" will get an active class and the window will scroll to that location. But, after that has happened say the user manually begins scrolling down the page, I want the active class to be removed. The problem I am running up against now is that the below function will happen when the scrolling animation from a clicked anchor is taking place. How can I disable this only when the window is being scrolled from a clicked anchor?

$(window).scroll(function() {
    $('a[href^=#]').removeClass('active');
});

Here is the scrolling anchor script I am working with.

/*******

    *** Anchor Slider by Cedric Dugas   ***
    *** Http://www.position-absolute.com ***

    Never have an anchor jumping your content, slide it.

    Don't forget to put an id to your anchor !
    You can use and modify this script for any project you want, but please leave this comment as credit.

*****/

jQuery.fn.anchorAnimate = function(settings) {

    settings = jQuery.extend({
        speed : 500
    }, settings);   

    return this.each(function(){
        var caller = this
        $(caller).click(function (event) {  
            event.preventDefault()
            var locationHref = window.location.href
            var elementClick = $(caller).attr("href")

            var destination = $(elementClick).offset().top;
            $("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination}, settings.speed, 'easeOutCubic', function() {
                window.location.hash = elementClick
            });
            return false;
        })
    })
}

And lastly, my jQuery

// Scrolling Anchors

$('[href^=#]').anchorAnimate();

// Active Class For Clicked Anchors

var anchorscroll = $('a[href^=#]')

anchorscroll.click(function(){
var anchorlocation = $(this).attr("href");
    anchorscroll.removeClass('active');
    $(this).addClass('active');
    $('a[href='+anchorlocation+']').addClass('active');
});
+2  A: 

Try changing plugin like this (added lines are marked):

jQuery.fn.anchorAnimate = function (settings) {

    settings = jQuery.extend({
        speed: 500
    }, settings);

    var scrollFn = function () { // added
        $('[href^=#]').removeClass('active');
        $(window).unbind('scroll', scrollFn);
    }

    return this.each(function () {
        var caller = this
        $(caller).click(function (event) {
            event.preventDefault()
            var locationHref = window.location.href
            var elementClick = $(caller).attr("href")

            var destination = $(elementClick).offset().top;
            $("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination }, settings.speed, 'easeOutCubic', function () {
                window.location.hash = elementClick
                $('[href^=#]').removeClass('active'); // added
                $('[href^=' + elementClick + ']').addClass('active'); // added
                $(window).scroll(scrollFn); // added
            });
            return false;
        })
    })
}
$(document).ready(function () {
    $('[href^=#]').anchorAnimate();
});

EDIT: Explanation:

Animate method takes callback as its final parameter. This callback is called after animation finishes. See http://api.jquery.com/animate/.

So on anchor click an animation will start. When it finishes, it will change window.location.hash (original plugin code)

Then it will remove "active" class from all links pointing to this document (for the cases where user clicks on the links without scrolling in between).

Then it will add "active" class to the anchor that user just clicked

Finally it will bind an event handler to window scroll. By biding it after animation, we ensure, that it doesn't fire during animation.

Now when user scrolls using mouse or keys, our event handler is fired. We remove the active class from all the links and unbind the handler so it doesn't get called again before user clicks another link.

When another link is clicked, whole process is repeated.

Luc
This ALMOST works, I have a few questions though. Mainly with the scrollFn, what is the unbind doing?Using this method the active class will be added on click, then be removed while the window scrolls, then go back onto the anchor once the animation is complete, making more of a flickering appearance. How could I adjust it to either only add the active class after the animation is complete, or leave it on while the scrolling animation is taking place?
jaasum
@Jaasum: I added explanation to the post.If it doesn't work for you, you'll need to give me some more info, since it is working in my FF3.6
Luc
There were a few things in the CSS that I switched around with hover states. This is working perfectly, thank you.
jaasum
A: 

Check out my answer to this question... it should give you an idea of how I accomplished something similar to what you want.

fudgey
That is a nice technique, but I don't think it's quite what I am looking for. This should only happen when the user clicks one of the anchors, otherwise nothing happens. It appears that yours sets a class of 'selected' once the window lands on any anchor location. I guess it's a little beyond what I am trying to do :)
jaasum