How to make buttons remain 'active' after they're clicked?
Solution 1
You need to identify the page you are currently on.
var page = window.location.href;
page = page.substr((page.lastIndexOf('/') + 1));
page = page.split('.');
page = page[0];
//At this point you will have the current page only with no extension or query paramaters
//I.E. "About Us"
page = page.toUpperCase();
//This accounts for upper or lower casing of urls by browsers.
switch(page) {
case "ABOUT US":
$('#About').addClass('< name of active button class >');
break;
case "SERVICES":
$('#Services').addClass('< name of active button class >');
break;
case "CONTACT US":
$('#Contact').addClass('< name of active button class >');
break;
}
If you're not using jQuery replace this line:
$('#< element name >').addClass('< name of active button class >');
with this line:
document.getElementById("< element name >").className += " < name of active button class >";
Hope this helps.
Solution 2
Best just to stick to using CSS classes with some JS. This way you can mix both styles for the pseudoclass (:hover) as well as the CSS class.
$('.myButtonLink').click(function() {
$(this).addClass('active_class');
});
Or if you want to toggle it.
$('.myButtonLink').click(function() {
$(this).toggleClass('active_class');
});
This way if there any changes in your layout, you only have to update the CSS styles that are apart of that class and not have to update your JavaScript code.
You can use the window or localStorage element to keep stage across page refreshes.
var key = getStorageKeyFromLink(link);
window.activeStateLookup = window.activeStateLookup || {};
window.activeStateLookup[key] = {
element : link
};
Now when your page loads you can just update all the images:
window.onload = function() {
var lookup = window.activeStateLookup || {};
for(var key in lookup) {
var element = lookup[key].element;
element.addClass('active_class');
}
}
--- EDIT ---
Here's your DEMO.
The example uses localStorage, but it would work the same with the window object. Be sure to copy and paste the code and try it out on your local machine since jsfiddle has some blocks against what's going on.
Solution 3
You could use a little jquery
to see what the url
is, parse it and then re-apply the active
class to the appropriate link.
I.E ( i haven't tested this... it's more of an idea...)
var path = window.location.pathname;
$(a).each(function(){
if (path.indexOf($(this).prop("href")) > 0){
$(this).child("button").addClass("active");
break;
}
});
OCD
Updated on July 26, 2022Comments
-
OCD almost 2 years
I'm currently using the following code for my menu items:
HTML
<li> <a id="About" class="button" href="About Us.cshtml">About Us</a> </li> <li style="margin-left: 30px;"> <a id="Services" class="button" href="Services.cshtml">Services</a> </li> <li style="margin-left: 30px;"> <a id="Contact" class="button" href="Contact Us.cshtml">Contact Us</a> </li>
CSS
#About {background-image: url(../Buttons/About.png); width: 87px;} #Services {background-image: url(../Buttons/Services.png); width: 112px;} #Contact {background-image: url(../Buttons/Contact.png); width: 117px;} a.button {height: 20px; display: inline-block; background-repeat: no-repeat} a.button:hover {background-position: 0 -20px;} a.button:active {background-position: 0 -40px;}
I need to get the buttons to remain in the 'active' state after they're clicked and the page loads/refreshes etc.
If the solution requires javascript, please bear in mind that I'm a rank amateur so I'll need any explanations in layman's terms (preferably with examples).
-
xiaoyi over 11 yearsI don't think this question deserve -1.
-
bozdoz over 11 yearsYou want it to remain active until the page loads, or even after the page loads? The latter requires you to get the URL with javascript (not impossible).
-
Ryan B over 11 yearsThe common approach is to apply an additional class to the link that mimics the
:hover
, are you using PHP or anything? -
Wesley Murch over 11 yearsI don't think this question deserves +7 either... but hey, why not?
-
Darren Wainwright over 11 yearsI think the -1 might have come because more or less the same question was asked by Leon 45 mins before stackoverflow.com/questions/13648674/…
-
Wesley Murch over 11 yearsAm I correct that you are looking for something like
:visited
? See also: hacks.mozilla.org/2010/03/… -
Darren Wainwright over 11 years@WesleyMurch - visited would end up having the style applied to all clicked-links. Eventually, after navigating through, all links would end up the same color.
-
Matheus Azevedo over 11 yearsI think that the only reliable approach is to use server-side scripting or cookies.
-
Wesley Murch over 11 years@Darren: Solved by
specificSelector:visited
, in this case there are hrefs and ids to use, but I realize that's not a solution anyhow... but I don't get it - each link should permanently change once clicked? -
Darren Wainwright over 11 years@WesleyMurch. That's what
visited
does..it's to give the user a visual clue of links they have already visited before. Ever noticed that when you search Google some links might be purple; you have alreadyvisited
those ones before. Also AFAIK, you can only apply:visited
to links, and not buttons, and have it work as expected. -
OCD over 11 years@ bozdoz - After the page loads.
-
OCD over 11 years@Ryan B - I'm not entirely sure what you mean by adding an additional class to mimic :hover. I'm not currently using anything other than straight-up html & css. I'd rather keep it that way but I'm prepared to get some JS involved...not that I know JS too well.
-
OCD over 11 years@ Darren - Actually, that question was relating to getting the mouseover and active states working while using a combination of IDs and classes. I mentioned in that thread that I would then be looking to keep the buttons in the active state after they're clicked and this would likely require JS so I'd ask the JS question on a separate thread - since it's a separate question.
-
OCD over 11 years@ Wesley Murch & Darren - No, they should not be permanently active once clicked - only while the user is on that page. I've seen various examples of JS knocking about that somehow sets the relevant class on the clicked item and also removes that same class from other items...so clicking on 'About' would result in that button becoming (and remaining) active, but then clicking on 'Services' would remove the active attribute from the 'About' button and add it to the 'Services' button etc.
-
Darren Wainwright over 11 years@LeonLawrence - I understand that, I was letting Wesley know why
visited
is not the correct solution. I put an answer on here about an hour ago with an idea. It might help you.
-
-
xiaoyi over 11 yearsI need to get the buttons to remain in the 'active' state after they're clicked and the page loads/refreshes etc. why this is correct?
-
War10ck over 11 years@Garry If the page refreshes, you'll lose the class you just added.
-
xiaoyi over 11 yearsI need to get the buttons to remain in the 'active' state after they're clicked and the page loads/refreshes etc. why this is correct?
-
War10ck over 11 years@matsko Does this not have the same problem as Garry's example. Once the page reloads, the DOM is cleared meaning the class you just added becomes lost and irrelevant. Classes don't stay from page to page.
-
matsko over 11 yearsJust use localStorage to maintain the state then. Or use the window element.
-
Matheus Azevedo over 11 yearsThis way, only the page he's viewing will have the 'active' class. I think he wants to keep all visited pages 'active'
-
War10ck over 11 years@MatheusAzevedo That needs to be clarified. It doesn't make sense to make every button that you ever pressed active. That would be considered visited. If I'm on "contact us" and I came from "about us", "contact us" is active while "about us" was visited. If that is indeed what is desired though, then just use the :visited CSS styling of <a> tags.
-
OCD over 11 yearsActually, if this solution results in only the current page being 'active' then that's exactly what I'm looking for. I'm no JS expert though...where exactly would I need to insert the above code? Additionally, what is "< element name >" referring to? should I be replacing this with something?
-
OCD over 11 yearsMight seem like a silly question but am I supposed to paste the above into a .js file and reference it in the <head> of my webpages? Either way, Webmatrix is flagging up: "Can't have 'break' outside of loop". The buttons don't remain active either. I appreciate the help though. I'm lost otherwise - could you clarify? Thanks.
-
Darren Wainwright over 11 yearsAs mentioned, not tested, just an example. Though remove the break and try. the
each
is actually performing a loop - it'sjquery
. You would typically put javascript in the head of your page. For this one to work you would also need to reference thejquery
script. go to jquery.com for the library and installation help. -
Darren Wainwright over 11 yearsSome others have said server-side is also an option. I guess for us to help you more you need to say what languages you are capable in.
-
War10ck over 11 years@LeonLawrence The element name would be the id property of the button. (I.E. "About", "Services", or "Contact"). As far as the class goes, you place the name of the CSS class you created. The above code would need to be placed in a section that runs on document ready.
$(document).ready(function () { _Place Code Here_ } });
. My apologies, I should have asked too. Are you using the jQuery framework or just plain javascript? -
War10ck over 11 years@LeonLawrence If you not using jQuery you can still determine when the document is ready and apply this coding by applying a listener as follows: `document.addEventListener( "DOMContentLoaded", function(){ document.removeEventListener( "DOMContentLoaded", arguments.callee, false ); < Add above code here > }, false );
-
OCD over 11 yearsI'm not currently using jQuery or any other framework. So I guess it's just javascript. The whole site is just CSS and HTML until now. Pathetic as it may sound, those are the only languages/utilities I'm even loosely familiar with. To be honest, javascript is largely gobbledigook to me. Darren has suggested I install jQuery. I'm happy to try this if it'll help. p.s. I have no idea what 'document ready' is/means.
-
OCD over 11 years@ War10ck - ok, I'll try applying the listener & come back to you.
-
OCD over 11 yearsVaguely capable in html & css. That's about it... :-/
-
Darren Wainwright over 11 yearsYep, you're going to need to learn some
javascript
to do this on the browser end. Highly recommend usingjquery
as it encapsulates a LOT of what you need to do, and can be done with simple calls. -
War10ck over 11 years@LeonLawrence You are all good man. That's not pathetic at all. You got to start somewhere. JavaScript can be a bit tricky as its got some work arounds that have to be made to get some things to work correctly. And I'm sure you'll find sometimes things never look the same in different browsers. Ah the joys of web dev. All good though man. My apologies for being a little vague on 'document ready'. The DOM is the document object model (basically a tree of all your html elements on the page). You can view this link for more clarity. DOM.
-
War10ck over 11 years@LeonLawrence When a document is "ready", it means the browser has parsed all the HTML code and rendered it on the page in the DOM itself (in other words, your code has been successfully applied to the page). You have to wait for this to occur as you're applying JavaScript to an element on the page. If the JavaScript ran before the element was loaded, the browser would have nothing to add the class to and the button would be rendered as normal without the additional 'active' styling that you're applying.
-
OCD over 11 years@ matsko - 1. I do not require 'toggle' functionality. Therefore, do I need to implement the 1st, 3rd and 4th blocks of code you have provided?. 2. Am I to assume that I should replace '.myButtonLink' with '.button' since this is class I am using? or should I replace with the id e.g. 'About'? 3. Should I be replacing 'active_class' with '.button:active'? - please clarify. 4. Do I need to encapsulate each of these 3 blocks of code in <script> tags? where should I insert them? can I simply include all 3 in the same <script> tag?
-
matsko over 11 yearsMy post is a bit patched up because I changed and added things so quickly. Take a look at the demo that I posted. Basically you can just put the JavaScript code into it's own file and include that with a script tag as well as script tag for jquery right before. Then include the CSS contents into it's own file and link it to the page using the <link> element.
-
OCD over 11 years@ matsko - So I realised that it wasn't me being completely stupid. I'm referencing jQuery properly and calling your code just fine. The thing is, if I replace the urls that the buttons are pointing to with '#', the buttons do indeed retain the active state - it just doesn't work once the page loads after clicking (when the buttons are pointing to their respective pages, of course). Any idea how to remedy this? Or will it turn out that server-side code really is the only way forward (as has been suggested)?
-
OCD over 11 years@ War10ck - I worked out where I was going wrong and eventually managed to get jQuery involved. Following that, your suggestion was the only one that worked - and it works well. So props to you and thanks for your help and for taking the time to explain. Massively appreciated!
-
War10ck over 11 years@LeonLawrence Never a problem man. Always glad to assist. Good luck and happy coding!