Solved

Animated scroll to anchor on page from a js accordion menu

Posted on 2010-09-06
5
1,121 Views
Last Modified: 2012-05-10
I've got jquery accordion menu. When the buttons are clicked in that menu i want the page to scroll (animated) down to an anchor on the page.
I can get both of those to work individually but not together. It seems they are clashing in some way.
Here's the code:
<script>
$(function(){
    $('ul li a').click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'')
        && location.hostname == this.hostname) {
            var $target = $(this.hash);
            $target = $target.length && $target || $('[name=' + this.hash.slice(1) +']');
            if ($target.length) {
                var targetOffset = $target.offset().top;
                $('html,body').animate({scrollTop: targetOffset}, 1000);
                return false;
            }
        }
    });
});
</script>

Open in new window

/* 
Simple JQuery menu.
HTML structure to use:

Notes: 

Each menu MUST have a class 'menu' set. If the menu doesn't have this, the JS won't make it dynamic
If you want a panel to be expanded at page load, give the containing LI element the classname 'expand'.
Use this to set the right state in your page (generation) code.

Optional extra classnames for the UL element that holds an accordion:

noaccordion : no accordion functionality
collapsible : menu works like an accordion but can be fully collapsed

<ul class="menu [optional class] [optional class]">
<li><a href="#">Sub menu heading</a>
<ul>
<li><a href="http://site.com/">Link</a></li>
<li><a href="http://site.com/">Link</a></li>
<li><a href="http://site.com/">Link</a></li>
...
...
</ul>
// This item is open at page load time
<li class="expand"><a href="#">Sub menu heading</a>
<ul>
<li><a href="http://site.com/">Link</a></li>
<li><a href="http://site.com/">Link</a></li>
<li><a href="http://site.com/">Link</a></li>
...
...
</ul>
...
...
</ul>

Copyright 2007-2010 by Marco van Hylckama Vlieg

web: http://www.i-marco.nl/weblog/
email: marco@i-marco.nl

Free to use any way you like.
*/


jQuery.fn.initMenu = function() {  
    return this.each(function(){
        var theMenu = $(this).get(0);
        $('.acitem', this).hide();
        $('li.expand > .acitem', this).show();
        $('li.expand > .acitem', this).prev().addClass('active');
        $('li a', this).click(
            function(e) {
                e.stopImmediatePropagation();
                var theElement = $(this).next();
                var parent = this.parentNode.parentNode;
                if($(parent).hasClass('noaccordion')) {
                    if(theElement[0] === undefined) {
                        window.location.href = this.href;
                    }
                    $(theElement).slideToggle('normal', function() {
                        if ($(this).is(':visible')) {
                            $(this).prev().addClass('active');
                        }
                        else {
                            $(this).prev().removeClass('active');
                        }    
                    });
                    return false;
                }
                else {
                    if(theElement.hasClass('acitem') && theElement.is(':visible')) {
                        if($(parent).hasClass('collapsible')) {
                            $('.acitem:visible', parent).first().slideUp('normal', 
                            function() {
                                $(this).prev().removeClass('active');
                            }
                        );
                        return false;  
                    }
                    return false;
                }
                if(theElement.hasClass('acitem') && !theElement.is(':visible')) {         
                    $('.acitem:visible', parent).first().slideUp('normal', function() {
                        $(this).prev().removeClass('active');
                    });
                    theElement.slideDown('normal', function() {
                        $(this).prev().addClass('active');
                    });
                    return false;
                }
            }
        }
    );
});
};

$(document).ready(function() {$('.menu').initMenu();});

Open in new window

0
Comment
Question by:George-TCC
  • 3
  • 2
5 Comments
 
LVL 40

Expert Comment

by:gurvinder372
ID: 33609982
<<I can get both of those to work individually but not together>>
what does this mean? how did you tested individually? How should the script determine which anchor to scroll to when you click on an anchor in the menu list?


0
 

Author Comment

by:George-TCC
ID: 33613837
I can get the menu to work by itself and i can get the scrolling anchors to work by themselves but if i try to control the anchors with the menu it doesn't work.
In the menu in the li there will be an a tag to go to an id.
(This is not displayed in the current code)
eg. <li><a href="#anchor1">Anchor1</a>


0
 
LVL 40

Expert Comment

by:gurvinder372
ID: 33615889
Hmm...

In the approach you have mentioned in your last reply, you know the anchor tag you need to scroll down to by its id.
But if you do not have the id, or there is no mapping of the anchor tags (both above and below) available, how do you determine which anchor tag you should scroll down to.

If you want to map the anchor tags as per their order in both list, then
using this you can find the index of the item you have clicked
http://api.jquery.com/index/
using this you can access the item of the same index in another list
http://api.jquery.com/nth-child-selector/

0
 

Author Comment

by:George-TCC
ID: 33622686
The above code is just an example.
The nave would have to have something like <li><a href="#anchor1">Anchor1</a>
in it. Then somewhere down the page  in the html would have to be the anchor for the  button to link to.
The problem is that the button in the nav is inside an <li> If i make a button outside of the nav it scrolls down to the anchor properly.
Once the button is in the accordion nav and inside the <li> it no longer works.
0
 
LVL 40

Accepted Solution

by:
gurvinder372 earned 500 total points
ID: 33634095
If the link you are clicking has the information about which element you have to scroll down to (in the href attribute), then
you can simply use the following method

 $('ul li a').click(function()
 {
            var $target = $("#" + this.attr("href"));
            $target = $target.length && $target || $('[name=' + this.hash.slice(1) +']');
            if ($target.length) {
                var targetOffset = $target.offset().top;
                $('html,body').animate({scrollTop: targetOffset}, 1000);
                return false;
            }
});
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This is a PowerShell web interface I use to manage some task as a network administrator. Clicking an action button on the left frame will display a form in the middle frame to input some data in textboxes, process this data in PowerShell and display…
Building a website can seem like a daunting task to the uninitiated but it really only requires knowledge of two basic languages: HTML and CSS.
In this tutorial viewers will learn how to customize the background color and font color of highlighted text using the ::selection element in CSS Begin by defining the selected text as an element in CSS by typing "::selection": Style the ::selection…
In this tutorial viewers will learn how to embed an audio file in a webpage using HTML5. Ensure your DOCTYPE declaration is set to HTML5: : The declaration should display (CODE) HTML5 is supported by the most recent versions of all major browsers…

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now