I am trying to create a navigation menu using css and js. I have styled the necessary classes, and nav works with js animation, however I am having a problem changing the class of li to active onclick by the user, and saving this in local storage so that it remains when the page refreshes.
This is the code that I have now:
http://codepen.io/anon/pen/wfpti
Javascript:
var foundActive = false, activeElement, linePosition = 0, menuLine = $("#navmenu #menu-line"), lineWidth, defaultPosition, defaultWidth;
$("#navmenu > ul > li").each(function() {
if ($(this).hasClass('active')) {
activeElement = $(this);
foundActive = true;
}
});
Html:
<div id='navmenu'>
<ul>
<li class='active'><a href='link1.php'>link1</a></li>
<li><a href='link2.php'>link2</a></li>
<li><a href='link3.php'>link3</a></li>
<li><a href='link4.php'>link4</a></li>
<li><a href='link5.php'>link5</a></li>
<li><a href='link6.php'>link6</a></li>
<li><a href='link7.php'>link7</a></li>
</ul>
</div>
What I would like to achieve is that when I press, for example, "link3" is that it goes to link3.php, and the navigation menu then shows link3 as the active class link, while removing the previous active class for link1.
Just try to add class on click event this function will stop your active links. this may works for you. if you want to add active class after refreshing a page then store it to javascript cookies.
$("#navmenu > ul > li").click(function()
{
$(this).closest('ul').find('li').each(function()
{
$(this).removeClass('active');
});
$(this).addClass('active');
defaultWidth = lineWidth = activeElement.width();
defaultPosition = linePosition = activeElement.position().left;
menuLine.css("width", lineWidth);
menuLine.css("left", linePosition);
});
Related
I have a question for you. I'm trying to use localstorage in my dropdown toggle menu. I have the following HTML code:
<li class="nav-item" id="sidebar">
<a class="sidebar-heading" href="#thirdSubmenu" data-toggle="collapse"
class="dropdown-toggle">Anagrafica</a>
<ul class="collapse list-unstyled" id="thirdSubmenu">
<li>
<a class="nav-link" href="">
<span data-feather="database"></span>
Categorie Materiale</a>
</li>
<li>
<a class="nav-link" href="">
<span data-feather="database"></span>
Sottocategorie Materiale</a>
</li>
..
I want that, when I click on Anagrafica and dropdown menu is opened, when I update my page it remains open too, storing if the dropdwon was opened or not. I'have tried the following code but does work. I'm not good at jQuery, so I hope that someone of you could help me.
Here my jQuery code:
$("#thirdSubmenu li a").on("click", function() {
var container = $(this).closest("li");
var selected_item_index = $("#thirdSubmenu li a").index(container);
localStorage.setItem("sidebar_selected", selected_item_index );
});
$(function() {
$("#thirdSubmenu li").eq(parseInt(localStorage.getItem("selected_item_index "))).addClass("active");
});
You want to index the parent <li> within it's siblings
Try changing
$("#thirdSubmenu li a").on("click", function() {
var container = $(this).closest("li");
var selected_item_index = $("#thirdSubmenu li a").index(container);
localStorage.setItem("sidebar_selected", selected_item_index );
});
To
$("#thirdSubmenu li a").on("click", function() {
// get index of parent `<li>` within it's siblings
var selected_item_index = $(this).parent().index();
localStorage.setItem("sidebar_selected", selected_item_index );
});
You can also go with JavaScript Cookies. Store a value in a cookie
I've found many posts on how to add the active class to a nav link via jquery, but nothing on how to maintain the active state after the nav link is clicked.
Using code found on this site, I'm removing and adding the active class onclick. In an attempt to keep this active state after navigating/reloading, my thought is to set session variables via onclick, and re-add the active class.
What I have is not working.
This seems to work, but doesn't seem to be best-practice, by today's standards.
HMTL:
<nav>
<a href="about.xhtml" id="about" >About</a>
<span class="nav_divide"></span>
<a href="work.xhtml" id="work" >Work</a>
<span class="nav_divide"></span>
<a href="mission.xhtml" id="mission" >Mission</a>
<span class="nav_divide"></span>
<a href="contact.xhtml" id="contact" >Contact</a>
</nav>
CSS:
nav a.active {
border-bottom: 3px solid #d10f0f;
}
Script:
//Check for session variables.
$(document).ready(function() {
//If 'page' session is defined
if (window.sessionStorage.pageSession) {
// make selected nav option active.
var activeTab = '#' + window.sessionStorage.pageSession;
$(activeTab).addClass('active');
} else {
// If pageSession is not defined, you're at home
window.sessionStorage.pageSession = ('page', 'home');
}
//Set link location for page refresh/reload
});
// Place or remove nav active state.
$(document).on('click','nav a',function(){
//Set 'page' and 'link' variables based on nav values.
var page = this.id;
var link = this.href;
// Set 'page' and 'link' session variables based on nav values.
var window.sessionStorage.pageSession = ('page', page);
var window.sessionStorage.linkSession = ('link', link);
// Update classes.
$('nav .active').removeClass('active');
$(this).addClass('active');
// Link to nav ahref.
window.location = sessionStorage.linkSession;
});
You can use localStorage! this is an example:
//Check for session variables.
$(document).ready(function() {
// Set paramenters obj for initialization
let paramObj = {page:'current-page-name',link:location.href};
// Initialize pageSession obj to storage the current page
localStorage.setItem('pageSession', JSON.stringify(paramObj));
// Retrieve page session settings updated
let pageStorage = localStorage.getItem('pageSession') != undefined ? JSON.parse(localStorage.getItem('pageSession')) : paramObj;
// make selected nav option active.
let activeTab = '#' + pageStorage.page;
$(activeTab).addClass('active');
//Set link location for page refresh/reload
$(document).on('click','nav a',function(e){
e.preventDefault();
//Set 'page' and 'link' variables based on nav values.
let page = JSON.parse(localStorage.getItem('pageSession')).page;
let link = JSON.parse(localStorage.getItem('pageSession')).link;
// Set 'page' and 'link' session variables based on nav values.
localStorage.setItem('pageSession', JSON.stringify({page:$(this).attr('id'), link:$(this).attr('href')}));
// Update classes.
$('nav .active').removeClass('active');
$(this).addClass('active');
// Link to nav ahref.
window.location = $(this).attr('href');
});
});
nav a.active {
border-bottom: 3px solid #d10f0f;
}
<nav>
<a href="javascript:;" id="home" >Home</a>
<span class="nav_divide"></span>
<a href="javascript:;" id="about" >About</a>
<span class="nav_divide"></span>
<a href="javascript:;" id="work" >Work</a>
<span class="nav_divide"></span>
<a href="javascript:;" id="mission" >Mission</a>
<span class="nav_divide"></span>
<a href="javascript:;" id="contact" >Contact</a>
</nav>
There are a lot of ways for doing that. This is only one of ways!
--------------- EDITED ---------------
Now the code initialize pageSession on every page, so the JSON.parse(...) was solved!
Try it here jsfiddle. Now it works!
I hope it help.
I want menu item to be highlighted when an item is selected in the drop down. I tried following code. Code is working if I prevent default behavior of a which I don't want, So I tried using local storage but it is not working, only page refreshes and default Home item of menu is highlighted.
Menu
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li class="dropdown">
Fire & Water <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>Water Damage</li>
<li>Fire Damage</li>
<li>Storm Damage</li>
<li>Commercial Restoration</li>
</ul>
</li>
<li class="dropdown">
Mold <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>Mold Remediation</li>
<li>What is Black Mold?</li>
<li>Mold "Removal" vs Remediation</li>
<li>Commercial Mold Remediation</li>
</ul>
</li>
</ul>
This is Working
$(document).ready(function(){
$(".dropdown-menu li a").click(function(e){
e.preventDefault();
var hrefs = $(this).attr('href');
alert("hrefs : " + hrefs);
$("li").removeClass('active');
$('a[href="' + hrefs + '"]').parents('li').addClass('active');
});
});
This is not working
$(document).ready(function(){
$(".dropdown-menu li a").click(function(){
var hrefs = $(this).attr('href');
alert("hrefs : " + hrefs);
localStorage.setItem('activeTab', hrefs);
var activeTab = localStorage.getItem('activeTab');
$("li").removeClass('active');
alert("activeTab : " + activeTab);
$('a[href="' + activeTab + '"]').parents('li').addClass('active');
});
});
I think, you have to apply active class on page load event not in click event. your code should be something like as below
$(document).ready(function(){
// activate left navigation based on current link
var current_url = window.location;
$('.dropdown-menu li a').filter(function () {
return this.href == current_url;
}).last().parents('li').addClass('active');
});
On every page load, you have to filter out link of current page from your navigation bar and then apply class active in parent. I have posted code for your explanation purpose you have to modify as per your HTML code structure.
Hope, this will work :)
I have a page with a list of menu items consisting of internal anchors. I'm trying to add an .active class to the selected item. It seems to work on load but when clicking a new item in that same page it doesn't.
When clicking a new menu item, I would like to remove all other active classes and add this class to the clicked item.
Sounds pretty simple, but I can't make it work.
I created this Fiddle, but it doesn't show the issue correctly, since I can't add hashes to the url.
However, maybe someone can point me in the right direction.
JS:
function setActiveLinks() {
var current = location.pathname;
$('.bs-docs-sidenav li a').each(function() {
var $this = $(this);
// Get hash value
var $hash = location.href.substr(location.href.indexOf('#') + 1);
if ($this.attr('href') == '#' + $hash) {
$this.parent().addClass('active');
}
})
}
setActiveLinks();
$('#leftmenu li a').click(function() {
$('#leftmenu li').removeClass('active');
setActiveLinks();
});
HTML:
<ul class="nav bs-docs-sidenav">
<li>
Download
</li>
<li class="active">
What's included
<ul class="nav">
<li class="active">Precompiled</li>
<li>Source code</li>
</ul>
</li>
<li>
Compiling CSS and JavaScript
<ul class="nav">
<li>Installing Grunt</li>
<li>Available Grunt commands</li>
<li>Troubleshooting</li>
</ul>
</li>
</ul>
Thanks. :-)
You have wrong selector to bind click event on anchor element. also you don't need to call setActiveLinks() function(which sets class based on href) here.
You can use context of clicked anchor element to traverse to parent li and add class active in it:
var $navLIs = $('.nav li')
$navLIs.find('a').click(function() {
$navLIs.removeClass('active');
$(this).parent().addClass('active');
});
Working Demo
Here I have a list, what I want to do is I need to change the list ( li ) background color to different one after click on a specific list item. the thing is once it click on the link page will be redirected and refresh. please can me suggest a solution for to get this done?
<div id="main-menu">
<ul id="main-menu-list">
<li id="menu-home">Home</li>
<li id="menu-profile">My Profile</li>
<li id="menu-dashboard">My Dashboard</li>
<li id="menu-search">Search</li>
</ul>
</div>
what i did for this :
Java Script :
var make_button_active = function()
{
//Get item siblings
var siblings =($(this).siblings());
//Remove active class on all buttons
siblings.each(function (index)
{
$(this).removeClass('active');
}
)
//Add the clicked button class
$(this).addClass('active');
}
//Attach events to menu
$(document).ready(
function()
{
$("#main-menu li").click(make_button_active);
}
)
CSS :
#main-menu-list li.active {
background: #0040FF;
}
It's a little difficult to tell exactly what you want to do, but here's some quick and dirty (and untested) code:
/// when we click on an `a` tag inside the `#main-menu-list`...
$('#main-menu-list').on('click', 'a', function(e) {
// stop the link from firing
e.preventDefault();
e.stopPropagation();
// change the list item's background to green
$(this).closest('li').addClass('myClassName').css('background-color', 'green');
// do anything else, e.g. load in pages via ajax...
});
You could use CSS to apply the green background color, instead of jQuery:
.myClassName { background-color: green; }
This will stop the page from navigating, and I don't know if that's your intention. If you want to check the currently-loaded page against the menu to find the current item, you could do this (on page load) instead:
var currentPage = window.location.pathname;
$('#main-menu-list').find('a[href^="' + currentPage + '"]').closest('li').addClass('active');
EDIT:
Your amended Javascript code can be simplified to the following:
$('#main-menu li').on('click', 'a', function (e) {
e.preventDefault();
e.stopPropagation();
// only do the following if the clicked link isn't already active
if(!$(this).closest('li').hasClass('active')) {
$(this).closest('ul').find('.active').removeClass('active');
$(this).closest('li').addClass('active');
// load in your content via ajax, etc.
}
});
JSFiddle example
For each page you can add a class to the current list item that has "where the user is"..
CSS:
.selectedItem{
background-color: orange;//whatever color your want for the selected tab..
}
Then for each of your pages,
say you're in Dashboard.html
your menu code will look like:
<div id="main-menu">
<ul id="main-menu-list">
<li id="menu-home">Home</li>
<li id="menu-profile">My Profile</li>
<li id="menu-dashboard" class="selectedItem">My Dashboard</li>
<li id="menu-search">Search</li>
</ul>
</div>
in profile.html:
<div id="main-menu">
<ul id="main-menu-list">
<li id="menu-home">Home</li>
<li id="menu-profile" class="selectedItem">My Profile</li>
<li id="menu-dashboard">My Dashboard</li>
<li id="menu-search">Search</li>
</ul>
</div>
and so on..
You need to change the background color when the document is loaded (i.e. in document.ready).
Then you need a mechanism to connect the currently loaded page to one of your list items.
$(document).ready(function(){
//get the url from the current location or in some other way that suits your solution
//perhaps use window.location.pathname
var moduleId = "dashboard" // hardcoded to dashboard to make the point :);
$("#menu-"+moduleId).css("background-color", "#ccc");
});
http://jsfiddle.net/9JaVn/1/