SitePoint Sponsor

User Tag List

Results 1 to 21 of 21
  1. #1
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    217
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Highlight the active link in a navigation menu

    I wonder if the script is all right. Please review my code:

    Code:
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Menu</title>
    <style>
    ul {list-style-type:none; margin:0; padding:0;}
    li {display:inline;}
    a.active {background:red;}
    </style>
    </head>
    <body>
    <ul>
    <li><a href="http://www.example.com/home">Home</a></li>
    <li><a href="http://www.example.com/news">News</a></li>
    <li><a href="http://www.example.com/contact">Contact</a></li>
    <li><a href="http://www.example.com/about">About</a></li>
    </ul>
    <script>
    for (var i = 0; i < document.links.length; i++) {
        if (document.links[i].href == document.URL) {
            document.links[i].className = 'active';
        }
    }
    </script>
    </body>
    </html>
    It should highlight the current page link in the navigation bar.

  2. #2
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,892
    Mentioned
    211 Post(s)
    Tagged
    12 Thread(s)
    Works as expected for me.
    Is there a particular problem you are having?

  3. #3
    Mouse catcher silver trophy Stevie D's Avatar
    Join Date
    Mar 2006
    Location
    Yorkshire, UK
    Posts
    5,881
    Mentioned
    122 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Rain Lover View Post
    It should highlight the current page link in the navigation bar.
    One thing to be careful of is that that kind of matching can only work where the URL is only ever presented in a single format. So it might be that example.com/page, www.example.com/page, (www.)example.com/page/ and (www.)example.com/page/index.htm all resolve to the same page ... but the script can only go on the basis of what's in the address bar, so unless you can be certain that no other form of the URL will ever be used, or you have rewrite rules that visibly redirect every request to the preferred format, it is not a sufficiently robust system and is likely to fall over.

    There are better ways of doing it!

  4. #4
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,892
    Mentioned
    211 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by Stevie D View Post
    There are better ways of doing it!
    I would say so, too.
    The OP said in a previous thread that his site was on Google Sites and that additional constraints were in play.
    Maybe it's something to do with that?

  5. #5
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    If the many restrictions on Google Sites are a hindrance, you should consider deploying static pages. There are static sites generators, for different server-side languages. Using those, you will be able to keep the dynamic part when developing and generate static pages for deployment. Obviously, with these solutions, the active page link is not hand coded for each page.

  6. #6
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,117
    Mentioned
    448 Post(s)
    Tagged
    8 Thread(s)
    Quote Originally Posted by Rain Lover View Post
    Please review my code
    A small thing, but rather than a class of "active", consider something like "current", as "active" can end up being confused with the "active" state of a link (a:active), which is quite different.
    Facebook | Google+ | Twitter | Web Design Tips | Free Contact Form

    Forum Usage: Tips on posting code samples, images and more

    Forrest Gump: "IE is like a box of chocolates: you never know what you're gonna get."

  7. #7
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    217
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post
    Works as expected for me.
    Is there a particular problem you are having?
    No specific problem to mention. I'm not good a JavaScript and just wanted my code to be reviewed & checked by a JS expert like you.

  8. #8
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    217
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Stevie D View Post
    unless you can be certain that no other form of the URL will ever be used, or you have rewrite rules that visibly redirect every request to the preferred format, it is not a sufficiently robust system and is likely to fall over.
    Thanks for the tiny point! Google Sites doesn't support naked domains. The only problem is with the landing/home page, i.e. https://sites.google.com/site/my-site/ and https://sites.google.com/site/my-site/home go to the same page. It's a problem I need to think about. Maybe:

    Code:
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Menu</title>
    <style>
    ul {list-style-type:none; margin:0; padding:0;}
    li {display:inline;}
    a.active {background:red;}
    </style>
    </head>
    <body>
    <ul>
    <li><a href="http://www.example.com/home">Home</a></li>
    <li><a href="http://www.example.com/news">News</a></li>
    <li><a href="http://www.example.com/contact">Contact</a></li>
    <li><a href="http://www.example.com/about">About</a></li>
    </ul>
    <script>
    for (var i = 0; i < document.links.length; i++) {
        if (document.links[i].href == document.URL) {
            document.links[i].className = 'active';
        } else {document.links[0].className = 'active';}
    }
    </script>
    </body>
    </html>
    Needs to be reviewed by Pullo.

    There are better ways of doing it!
    I'd be grateful if you provided an alternative solution!

  9. #9
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    217
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by myty View Post
    If the many restrictions on Google Sites are a hindrance, you should consider deploying static pages. There are static sites generators, for different server-side languages. Using those, you will be able to keep the dynamic part when developing and generate static pages for deployment. Obviously, with these solutions, the active page link is not hand coded for each page.
    I read your post a couple of times and am still not sure what you mean: do you mean I should stop using Google Sites due to its limitations?

  10. #10
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    217
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ralph.m View Post
    A small thing, but rather than a class of "active", consider something like "current", as "active" can end up being confused with the "active" state of a link (a:active), which is quite different.
    Very true! Thank you!

  11. #11
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,892
    Mentioned
    211 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by Rain Lover View Post
    Needs to be reviewed by Pullo.


    It'll work, but it's brittle.
    Besides what Stevie has already pointed out this line:

    document.links[0].className = 'active'

    will change the class name of the first link it encounters to "active"
    What if your home link isn't the first?

    I don't know much about Google Sites - do you have an include file for your navigation, or what is the reason for trying to use JavaScript to set the styling?

  12. #12
    Mouse catcher silver trophy Stevie D's Avatar
    Join Date
    Mar 2006
    Location
    Yorkshire, UK
    Posts
    5,881
    Mentioned
    122 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Rain Lover View Post
    I'd be grateful if you provided an alternative solution!
    The easiest way is kinda clunky but works well enough:

    Give the <body> of each page a class name that (roughly) matches the name of the page, eg
    HTML Code:
    <body class="news">
    then in your navigation list, give each <li> the corresponding class, eg
    HTML Code:
    <ul>
    <li class="home"><a href="http://www.example.com/home">Home</a></li>
    <li class="news"><a href="http://www.example.com/news">News</a></li>
    <li class="contact"><a href="http://www.example.com/contact">Contact</a></li>
    <li class="about"><a href="http://www.example.com/about">About</a></li>
    </ul>
    and finally set your "current" style in the CSS using a list of comma-separated selector pairs, eg
    Code CSS:
    body.home li.home,
    body.news li.news,
    body.contact li.contact,
    body.about li.about 
    {background:red;}
    Note - commas go between pairs only, not in the middle of a pair and not after the last pair.

  13. #13
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    217
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post


    It'll work, but it's brittle.
    Besides what Stevie has already pointed out this line:

    document.links[0].className = 'active'

    will change the class name of the first link it encounters to "active"
    What if your home link isn't the first?
    It seems to have a problem even if my home link is the first:
    https://googledrive.com/host/0B5jOXz...DWm8/menu.html



    I don't know much about Google Sites - do you have an include file for your navigation, or what is the reason for trying to use JavaScript to set the styling?
    As I said you cannot use any scripting language or even CSS stylesheets in your Google Site page content area. However, you can use custom CSS and JavaScript in Google gadgets and embed them to your site as iframes. In Google Sites all you can do is use some inline CSS.
    Here's a sample Google Site and Google gadget:
    https://sites.google.com/site/michaelmccolin/test

  14. #14
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    217
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Stevie D View Post
    The easiest way is kinda clunky but works well enough:

    Give the <body> of each page a class name that (roughly) matches the name of the page
    I can't. The body class name is fixed by Google. Here's a Google Site:
    https://sites.google.com/site/michaelmccolin/

  15. #15
    Mouse catcher silver trophy Stevie D's Avatar
    Join Date
    Mar 2006
    Location
    Yorkshire, UK
    Posts
    5,881
    Mentioned
    122 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Rain Lover View Post
    I can't. The page ID is fixed by Google. Here's a Google Site:
    https://sites.google.com/site/michaelmccolin/
    Holy guacamole, batman, that is atrocious code

    Although the body ID is fixed, can you not add an additional class to it? (Discounting any limitations that may imposed by Google Sites, an element can have as many classes as you want)

    Although looking at how clunky that code is ... is your menu put there by some kind of include, or is it just hard coded into each page? If it's the latter, you might as well just manually put class="current" on the relevant list item on each page.

    Or ditch Google Sites and go for a system that isn't so utterly cruddy.

  16. #16
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,117
    Mentioned
    448 Post(s)
    Tagged
    8 Thread(s)
    Quote Originally Posted by Stevie D View Post
    Or ditch Google Sites and go for a system that isn't so utterly cruddy.[/font]
    +1. With hosting so incredibly cheap, I don't see any advantage to such restrictive hosting as this, but many downsides.
    Facebook | Google+ | Twitter | Web Design Tips | Free Contact Form

    Forum Usage: Tips on posting code samples, images and more

    Forrest Gump: "IE is like a box of chocolates: you never know what you're gonna get."

  17. #17
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,892
    Mentioned
    211 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by Rain Lover View Post
    It seems to have a problem even if my home link is the first
    Oh dear.
    Try this instead:

    Code:
    var active = 0;
    for (var i = 0; i < document.links.length; i++) {
        if (document.links[i].href === document.URL) {
            active = i;
        }
    }
    document.links[active].className = 'active';
    Does that help?

  18. #18
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    217
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Thumbs up

    Quote Originally Posted by Pullo View Post
    Oh dear.
    Try this instead:

    Code:
    var active = 0;
    for (var i = 0; i < document.links.length; i++) {
        if (document.links[i].href === document.URL) {
            active = i;
        }
    }
    document.links[active].className = 'active';
    Does that help?
    Works like a charm! Thank you very much!

  19. #19
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Rain Lover View Post
    I read your post a couple of times and am still not sure what you mean: do you mean I should stop using Google Sites due to its limitations?
    No.

    I meant you can circumvent problems like dynamically highlighting the active link in the menu, on client-side, by using the scripting feature, on server-side, in order to dynamically produce static pages that present the same feature...

    ...or just Google "static site generator".

    One example is harp: http://harpjs.com/. It's nodejs related technology. The part I'm talking about is called "compile and deploy".

    The compile process can result in static pages, where each page has the active class attribute added dynamically upon page generation rather then the pages having a JavaScript code included to be executed on client-side in order to determine the active link.

    You are basically moving the active link logic from client-side to server-side, or development-side, to be more accurate. After you generate the pages, you simply deploy them on Google Pages server, as static or almost entirely static pages.

  20. #20
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    217
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Stevie D View Post
    Holy guacamole, batman, that is atrocious code

    Although the body ID is fixed, can you not add an additional class to it?
    I was correcting my previous post when you answered -- no I can't change or add to the parent frame class.

  21. #21
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    217
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by myty View Post
    No.

    I meant you can circumvent problems like dynamically highlighting the active link in the menu, on client-side, by using the scripting feature, on server-side, in order to dynamically produce static pages that present the same feature...

    ...or just Google "static site generator".

    One example is harp: http://harpjs.com/. It's nodejs related technology. The part I'm talking about is called "compile and deploy".

    The compile process can result in static pages, where each page has the active class attribute added dynamically upon page generation rather then the pages having a JavaScript code included to be executed on client-side in order to determine the active link.

    You are basically moving the active link logic from client-side to server-side, or development-side, to be more accurate. After you generate the pages, you simply deploy them on Google Pages server, as static or almost entirely static pages.
    Thanks for the clarification!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •