Solved

Animated scroll to anchor on page from a js accordion menu

Posted on 2010-09-06
5
1,129 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Transaction Monitoring Vs. Real User Monitoring

Synthetic Transaction Monitoring Vs. Real User Monitoring: When To Use Each Approach? In this article, we will discuss two major monitoring approaches: Synthetic Transaction and Real User Monitoring.

Question has a verified solution.

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

International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
This article discusses how to create an extensible mechanism for linked drop downs.
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 style a corner ribbon overlay for an image using CSS Create a new class by typing ".Ribbon":  Define the class' "display:" as "inline-block": Define its "position:" as "relative": Define its "overflow:" as …

707 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