Question

My 'about' page uses a div content switch method (by Bill Posters) that allows me to put the mission, contact, etc, in the same container. It works really well until I try to link into a specific tab from another page. E.g., I have '/about/#mission' or '/about/#contact' that ends up linking to the first 'about' option of the content switch box rather than the correct option. I'd like a user to be able to click on 'Contact Us' from the homepage and get directed straight to the contact tab.

I've tried and tried to tweak the html and the jquery (even experimented with double anchors which I'm pretty sure is not a thing), I've added cookie recognition (doesn't quite work if the user hasn't accessed the page yet...), and I've searched forums extensively. Any ideas what I'm doing wrong or if there's a better way to do this? I'm guessing I'm making the issue much more complicated than necessary, but I'm pretty new to coding and, among other things, may not be using the correct search language.

I'd really appreciate any help!! I'm not married to this particular content switch method and am happy to try something else. Thanks very much!

Sara

function switchContent(obj) {

    obj = (!obj) ? 'sub1' : obj;

    var contentDivs =    document.getElementById('container').getElementsByTagName('div');
    for (i=0; i<contentDivs.length; i++) {
        if (contentDivs[i].id && contentDivs[i].id.indexOf('sub') != -1) {
            contentDivs[i].className = 'hide';
        }
    }
    document.getElementById(obj).className = '';

}


<div id="container">

<div id="sub1">content 1</div>
<div id="sub2" class="hide">content 2</div>
<div id="sub3" class="hide">content 3</div>

<div id="navigation">
    <a href="#" class="mininav" onclick="switchContent('sub1');   return false;">link 1</a>
    <a href="#" class="mininav" onclick="switchContent('sub2'); return false;">link 2</a>
    <a href="#" class="mininav" onclick="switchContent('sub3'); return false;">link 3</a>
</div>

Was it helpful?

Solution

Simply check the fragment identifier value in the location string. Pass the object we want to change in based on some conditional parameters.

if(window.location.hash){
    //fragment identifier such as '#mission', or '#about' has been found
    var sub = '',
        hsh = window.location.hash.split('#')[1]; // get string without # sign

    switch(hsh){
        case 'mission' :
            sub = 'sub1';
            break;
        case 'contact' :
            sub = 'sub2';
            break;
    }
    switchContent(sub);
}

In the above, we check for the fragment identifier. If found, we build a switch statement to prepare a string. Once we're done with the switch, we pass the string to the function which will in turn fire the content loader.

Ensure this code runs inside $(document).ready(function(){ }): otherwise the DOM elements may not be available.

Note: I would suggest changing this to build a more relationship friendly design pattern. Where the fragment identifier and the element containing the markup share some common string, such as a data attribute. <div data-rel="contact" id="sub1">. If this is done, then we no longer need to build a switch statement where we have to manually assign to a variable. If you're open to a more dynamic and fluid method, I'll be happy to build you out an example, just respond below.

Here's a more fluid method.

We should build relationships so we can keep things more sane. Let's take a look at how we should change the content divs.

<div class="info" id="mission">content 1</div>
<div class="info" id="about">content 2</div>
<div class="info" id="contact">content 3</div>

You'll see we modified the ids so they have a special relationship with not only the content inside, but the fragment identifier we're trying to work with. This way, we can reference that information back in our conditional statement that checks for the hash existence. We also added a new class, info which will allow us to make the code cleaner.

Now, let's clean up that content switcher function. Before, we were using a ternary operator to check if the obj exists and if not, assigning some arbitrary string to it; let's not do that.

function switchContent(did){
    $('.info').hide(0); //hide all the elements.
    $('div[id='+did+']').show();  //show only what we want!
}

That's it for our content switcher! Now let's build our conditional statement for the existence of the hash tag.

$(function(){
    if(window.location.hash){
        switchContent(window.location.hash.split('#')[1]);
    }  
});

We've shortened the code, and made it more fluid. In the above, we've wrapped our conditional check within the ready function, so that we know elements exist, and the page will work as intended.

Now let's clean up our anchors so they'll work even if there's no javascript enabled.

<a href="#mission" class="mininav">link 1</a>
<a href="#about" class="mininav">link 2</a>
<a href="#contact" class="mininav">link 3</a>

Great. Now that's much cleaner. No messy inline click functions or random string identifiers. Let's make it work.

$('#navigation a').click(function(e){
    e.preventDefault(); //we don't want the default jumping behavior
    switchContent($(this).prop('href').split('#')[1]);
});

Easy and clean! We capture the click event, stop the default behavior, then pass the href without the # sign to the function to switch our content! that's it!

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