Search code examples
javascriptjoomla

Change Css of link that matches #anchor


I want the link in the right sidebar to change color if it matches the #anchor in the current page's url.

Example> If this is the URL: https://help.thinkiq.com/documentation/visualization-and-analysis-tools/custom-content/extensions-xy-scatter-with-timeshift#solution

Then the link "Solution" in the "ON THIS PAGE" sidebar module should change to green.

I tried this but it doesn't work:

document.querySelectorAll('a[href="'+document.URL+'"]').forE‌​ach(function(elem){e‌​lem.className += ' current-link')});

And this in my custom.css

.current-link {
color: green;

}


Solution

  • I just ran this solution successfully on your live site by writing the following CSS and JS changes:

    CSS:

    .current-link {
        color: green !important;
    }
    

    JS

    document.querySelector('.sp-module ul>li>a[data-heading="' + window.location.hash.substr(1) + '"]').classList.add('current-link');
    

    Effectively, you just need to:

    1. access the hash value from the url
    2. build the hash value into your js selector
    3. add the desired class to the found element

    You need to ensure that your custom styling overrides other pre-existing stylings. !important did the job for me, but maybe it is possible to better specify the target element in your css.


    To add an event listener on each of the links in your list so that the green styling changes on every anchor click, choose from a range of js and jquery techniques/styles. I am using a plain js approach with a slight delay to ensure that the action is triggered after the url is updated. While testing on your live site, without a delay the event seemed to fire before the url was updated.

    document.querySelectorAll('.sp-module ul>li>a[data-heading]').forEach(function(elem) {
        elem.addEventListener("click", function() {
            setTimeout(function(){
                document.querySelectorAll('.sp-module ul>li>a[data-heading]').forEach(function(e) {
                    e.classList.toggle("current-link", e.dataset.heading == window.location.hash.substr(1));
                });
            }, 100); // 1/10 of a second
        });
    });
    

    The above adds a listener to each anchor element on page load. When any of the anchors are clicked, then all of the anchors will be iterated and the styling will be conditionally applied where appropriate.

    An alternative technique (which may actually be faster -- though I don't think it matters in this case) is to unconditionally remove the current-link class on ALL anchor elements, then only re-add the class to the newly appropriate anchor.