0

Jquery Removing & Adding 'Active' Class On LI Navigation Works With preventDefault, But Link No Longer

Jquery removing an adding active class to li nodes not working

I know it should be really basic to remove and add the active class to li's in order to highlight the current page's nav item, but I've been unable to get it to work.

I find that I must use e.preventDefault() to make it work, but when I do the link doesn't work but the highlighted nav item works. If I remove the preventDefault() then it navigates but doesn't highlight. I should say that my nav is sitting in a header.php include file. Here's what I have:

<ul class="myNav">
  <li><a href="index.php">Home</a></li>
  <li><a href="portfolio.php">Portfolio</a></li>
  <li><a href="about.php">About</a></li>
  <li><a href="contact.php">Contact</a></li>
</ul>

$('.myNav li a').click(function (e)
{
  e.preventDefault();
$('.myNav li').siblings().removeClass('active');
$(this).parent().addClass('active');
//var url = $(this).attr("href"); 
//window.location = url;
});

I tried to send the page to the clicked url and this loads the correct page, but it removes the class! I'd like to solve this, but I'd also like to understand why it isn't working correctly.

SmileBot
  • 19,393
  • 7
  • 65
  • 62
  • If you click a link and go to a new page then any changes made on the previous page via javascript will not have an effect. – bygrace May 21 '12 at 19:43
  • Do you really expect the link to work, go to another page, and then remember your function and highlight something on that new page. If so you've misunderstood! – adeneo May 21 '12 at 19:43
  • I see. So when it goes to the next page the change to the class attribute is lost and the default loads again. I see all kinds of posts all over the next for navigation links that are changing the class to active using jquery. It would seem odd if they were losing their class when the navigate to the new page. That would be totally pointless. So, I think it has something to do with the fact that it's in a header include file, but I'm not really sure why this is the case, or is it the fact that I'm adding a class to the li as opposed to the a node? – SmileBot May 21 '12 at 21:14

5 Answers5

2

I am afraid you can't achieve both highlighting and redirecting to the page at the same time using only jQuery. You should better try to add class active to respective li in your pages for example in index.php page add this line

  <li class="active"><a href="index.php">Home</a></li>

Because you cant preserve the state of menus using only jQuery. If this menu section of your page is in a seperate file like header.php then you have to detect which one is the current page. And can easily detect current page in php and add class="active" to corresponding li to highlight that.

Prasenjit Kumar Nag
  • 13,391
  • 3
  • 45
  • 57
1

when you navigate out of the page, whatever you did in javascript will be lost. Only way would be for your server program to set the 'active' flag, maybe by adding a query parameter to the link, or by checking the program's url

Rodolfo
  • 4,155
  • 23
  • 38
1

You have to do this in PHP by detecting the current url and comparing that the the url of the nodes in your navigation. Check this out: How can I get the current page's full URL on a Windows/IIS server?

Community
  • 1
  • 1
bygrace
  • 5,868
  • 1
  • 31
  • 58
  • Actually you don't have to do anything, there are cookies and local storage that can handle this with no problems at all, and if it's a regular HTML page, @Joy 's answer will work just fine, no PHP needed. – adeneo May 21 '12 at 19:46
  • 1
    Adeneo, the best way to handle this is on the server side. Cookies are unreliable, they can get deleted, local storage is not supported in all browsers. – aziz punjani May 21 '12 at 19:48
  • @Interstellar_Coder - agreed, but you still don't HAVE to use PHP, there are several ways to do it, and regular HTML, just adding a class, is the easiest one, and it really has nothing to do with PHP, even if the file where to be called index.php and ran thru the PHP parser. The answer given is to get the URL of the page and compare that to the navigation, can't we just as easily do that in JS ? – adeneo May 21 '12 at 19:50
  • adeneo, yes, you don't really need the url because you know which file is getting requested, it's just a matter of changing the markup depending on which php file is requested. I guess that's what joy is suggesting and also what i'm referring to. – aziz punjani May 21 '12 at 19:55
  • Yeah you could get the url in js and that is a perfectly valid option if the user is more familiar with JS than PHP. But it is better in PHP since JS could be disabled and there will be that split second between when the page starts loading and the JS runs. Not to mention that it is better practice to create html that wont change in the lifetime of a page in PHP rather than JS. – bygrace May 21 '12 at 19:55
  • Yes, doing it on the server is better, but there is no "have to use PHP", what if my server is running node.js, can I do it in javascript then ? Point being, there are many ways to do this, and you don't have to use PHP, and just having a list as a menu, and adding a class in the HTML for the active list element on each page is far easier then getting the URL and fiddling about with $_SERVER variables etc. – adeneo May 21 '12 at 19:59
  • Seems like you would have to get the URL in either case if you didn't want to use client side storage. – bygrace May 21 '12 at 20:02
  • I agree you're not bound to do it on the server, but given JS could be turned off on the client doing it on the server does seem like the best option, unless you've got a purely static page for some reason. – SmileBot May 24 '12 at 10:24
1

I ended up doing it in PHP like this:

<?php
//grab the current page name to use in the
$path = $_SERVER['PHP_SELF'];
$page = basename($path);
$page = basename($path, '.php');
?>

        <li<?php if ($page == 'index') echo 'class="active"';?>><a href="index.php">Home</a></li>
    <li <?php if ($page == 'portfolio') echo "class='active'"; ?> ><a href="portfolio.php">Portfolio</a></li>
    <li <?php if ($page == 'about') echo 'class="active"'; ?> ><a href="about.php">About</a></li>
    <li <?php if ($page == 'contact') echo 'class="active"'; ?> ><a href="contact.php">Contact</a></li>
SmileBot
  • 19,393
  • 7
  • 65
  • 62
0
var link = document.location.href.split('/').slice(-1);   // retrieve page name
$('#menuInner li a.active').removeClass('active');        // remove class 'active'
$('#menuInner li a[href$="'+link+'"]').parent().addClass('active');// and add it to a matching 
mipe34
  • 5,596
  • 3
  • 26
  • 38
MrQaidi
  • 1
  • 1
  • 1
  • 1