SanJeet Singh SanJeet Singh - 5 months ago 11
Javascript Question

How to keep navigation menu link styled persistently?

I have four items in my navigation menu

<nav>
<ul >
<li><a href="/a.html">ITEM A</a></li>
<li><a href="/b.html">ITEM B</a></li>
<li><a href="/c.html">ITEM C</a></li>
</ul>
</nav>


Hovering or clicking any of these items changes their color. But the color is gone after page refresh. If a user clicks on
b.html
, I want the menu item B to have a different color when the page reloads.How can I achieve that?

Am I making my question clear?

Thanks.

Answer

The simplest jQuery-based answer I can think of is to retrieve the href attribute-value and test that the URL of the current page ends with that attribute-value:

// getting the current location:
var url = document.location.href;

// iterating over each <a> element using filter(), using a
// more specific selector will reduce the work undertaken:
$('a').filter(function(i, a) {
    // i: the index of the current <a> element within the
    //    jQuery collection;
    // a: the current <a> DOM node.

    // String.prototype.endsWith() returns a Boolean, true
    // if the supplied string (url) ends with the supplied
    // argument (the attribute-value of the 'href'
    // attribute of the current <a> element):
    return url.endsWith( a.getAttribute('href') );

// we add the 'activeClass' class-name to those elements
// retained in the collection, to provide a styling hook:
}).addClass('activeClass');

Or, in the (somewhat likely) event that the browser doesn't support String.prototype.endsWith():

var url = document.location.href;
$('a').filter(function(i, a) {

    // retaining only those <a> elements whose
    // 'href' property (the absolute URL
    // derived from the <a> elements' href
    // attribute) is equal to the document location:
    return url == a.href;
}).addClass('activeClass');

Or, in plain JavaScript:

var aElements = Array.from(document.querySelectorAll('a')),
// or, in the event that ES6 Array.from() is unavailable:
// var aElements = Array.prototype.slice.call(document.querySelectorAll('a'), 0),
    url = document.location.href;

aElements.filter(Function (currentAnchor) {
    return currentAnchor.href == url;
}).forEach(function (currentAnchor) {
    currentAnchor.classList.add('activeClass');
});

Obviously all the above approaches require that a class be defined in your CSS to style the found links, such as – but obviously adjust to your own taste/aesthetic – the following:

a:active,
a.activeClass {
    color: #f90;
    text-decoration: underline;
}

It's worth noting – albeit somewhat optimistically – that at some point in the future, the pseudo-class of :local-link might style an <a> element pointing at the current page, for example:

a:active,
a:local-link {
    color: #f90;
    text-decoration: underline;
}

Though I'll note that, at the time of writing, this is not yet implemented, nor even listed on caniuse.com.

References:

Comments