Question

I have a hashchange function set up to show/hide different sections of an about page without having 7 separate pages. This all works fine, great infact, there's just one small thing that's bothering me, when the relevant content is shown on screen, eg: #about01 if you click on the menu button again the browser jumps down to the top of this div, which I don't want to happen.
Here's my jQuery:

jQuery(document).ready(function(){

    jQuery(window).on('hashchange', function(){
        var hashFound = determineContent();
        if(hashFound) return false;
    });

    function determineContent(){

        var hash = window.location.hash;
        jQuery('.about').hide();

        jQuery('.sub-menu').each(function(){

             if (jQuery(this).attr('hook') === hash.replace('#about', '')) {
               jQuery('#about'+jQuery(this).attr('hook')).fadeIn();
                 return true;
             }
        });

        jQuery('html, body').animate({scrollTop:0}, 'slow');
        return false;
    }

    determineContent();
});

HTML:

<div id="sub-menu">
        <li id="sub-menu-01" class="sub-menu" hook="01"><a href="#about01">TEST</a></li>
        <li id="sub-menu-02" class="sub-menu" hook="02"><a href="#about02">TEST</a></li>
        <li id="sub-menu-03" class="sub-menu" hook="03"><a href="#about03">TEST</a></li>
        <li id="sub-menu-04" class="sub-menu" hook="04"><a href="#about04">TEST</a></li>
        <li id="sub-menu-05" class="sub-menu" hook="05"><a href="#about05">TEST</a></li>
        <li id="sub-menu-06" class="sub-menu" hook="06"><a href="#about06">TEST</a></li>
        <li id="sub-menu-07" class="sub-menu" hook="07"><a href="#about07">TEST</a></li>
    </div>

<div id="about01" class="about">CONTENT HERE
</div>

<div id="about02" class="about">CONTENT HERE
</div>

<div id="about03" class="about">CONTENT HERE
</div>

<div id="about04" class="about">CONTENT HERE
</div>

<div id="about05" class="about">CONTENT HERE
</div>

<div id="about06" class="about">CONTENT HERE
</div>

<div id="about07" class="about">CONTENT HERE
</div>

Like I say, if #about01 is shown, and the user then clicks on #sub-menu-01 again, the window scrolls down to the top of this div, as is the normal behaviour for hashes in url's. Is the a way to prevent the default behaviour and not scroll to the top of this div on the click?
Also, I'm trying to figure out if there's a way to show #about01 on the page load of www.website.com/about instead of having to put in www.website.com/about/#about01 etc?

Was it helpful?

Solution

problem is in your jquery.each block.

"return true" inside jquery.each block will not return but continue for next items. Also, this will not return from your determineContent function, so the next code for scroll will also be executed and determineContent will always return false.

use a flag e.g.

var found = false;
JQuery.each(function(){
   if(found) return;
   //if your condition is true then found = true
})

if(found) return true;
//else continue the next line.

OTHER TIPS

$("#id").click(function(event) {
    event.preventDefault();

    //do stuff
});

http://api.jquery.com/event.preventDefault/

$('a').click(function(event){
    event.preventDefault();
});

The preventDefault() should stop any default events that an element has.

http://api.jquery.com/event.preventDefault/

Try this:

jQuery(window).on('hashchange', function(e){
    e.preventDefault();
    var hashFound = determineContent();
    if(hashFound) return false;
});

The preventDefault() method of the event object will avoid, as its name shows, the default behavior to be executed on that event. Since you'd like to avoid the normal behavior when the hash changes, that code should do.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top