0

it is fairly simple.

I want to make a current class and put it on a link that is currently active

like this : <li class="li current"><a>Link1</a></li>

but before that, the JS should get all of element with class="li", loop through it and remove the class=" current" if any.

after looping end, then add class=" current" to the element which triggers the event.

for example if user clicks on link3 then JS should remove the class=" current" on link1 and then add class=" current" on link3

it would look like this : <li class="li current"><a>link3</a></li>

it looks like I cannot use getElementsByClassName() for event listener. what should I do to make an event listener then?

the HTML

document.addEventListener("DOMContentLoaded",function(){
	var et = document.getElementsByClassName("li");
	for(i=0; i <et.length; i++){
			et[i].addEventListener("click",function(){
			 funclink(event);
			});
  };
});

function funclink(event){
	//first get all element with class "li" and remove class " current"
	//then add class " current" to the element which triggers the event
	var slink = document.getElementsByClassName("li");
	for(i =0; i < slink.length; i++){
		slink[i].className = slink[i].className.replace(" current","");
	}
	event.currentTarget.className += " current";
}
.current {
color : orange;
}
<ul id="navmenu">
	<li class="li current"><a href="#">Home</a></li>
	<li class="li"><a href="#">Call Service</a>
		<li class="li"><a class="a-left" href="#">Rental</a></li>
		<li class="li"><a class="a-left" href="#">Sales</a></li>
		
	</li>
 </ul>

1
  • You will have to loop over elements and add eventlistener Commented Mar 30, 2017 at 7:03

2 Answers 2

1

As commented before, you will have to loop over elements to add eventListener. document.getElementsByClassName will return a NodeList.

Also, if you are only calling your function with event param, you can just pass function ref instead.

Also, instead again fetching all lis, just fetch those lis that has class current. This will reduce number of iterations.

You should use classList instead of className. It has many helpful methods like add, remove and toggle.


Edit 1

As you need to retain the selected li even after refresh, you will have to use client storage or query param to tell your JS about the selected element.

For security reasons, SO does not provide access to localStorage, so you will have to copy code and debug on local files.

document.addEventListener("DOMContentLoaded", function() {
  var lis = document.getElementsByClassName("li")
  for (var i = 0; i < lis.length; i++) {
    lis[i].addEventListener("click", funclink.bind(lis[i], i));
  }
  
  initializeUI();
});

function funclink(index, event) {
  var lis = document.querySelectorAll('.li.current');
  for(var i = 0; i< lis.length; i++){
    lis[i].classList.remove('current');
  }
  this.classList.add('current');
  setIndex(index)
}

function initializeUI(){
  var lis = document.querySelectorAll('.li');
  var index = parseInt(locatStorage.getItem('liIndex'));
  lis[index || 0].classList.add("current");
}

function setIndex(index){
  localStorage.setItem("liIndex", index);
}

function blockAnchors(){
  var as = document.querySelectorAll('a');
  for(var i = 0; i< as.length; i++){
    as[i].onclick = function(){ 
      return false 
    }
  }
}
blockAnchors();
.current{
  background: #ddd;
}
<ul id="navmenu">
  <li class="li"><a href="?module=home">Home</a></li>
  <li class="li"><a href="?module=service">Call Service</a>
    <li class="li"><a class="a-left" href="?module=rental">Rental</a></li>
    <li class="li"><a class="a-left" href="?module=sales">Sales</a></li>

  </li>
</ul>

Note: I have added a blockAnchors to stop navigation on a's click. This is just for demonstration.

Sign up to request clarification or add additional context in comments.

9 Comments

yeah I managed to make it work thanks to your comment. but when I click on a link and the page loads, the current class is returned to original element. does that mean I cannot use JS to make the class=" current" stays on the active link?
Does clicking on a refreshes the page?
yes. unfortunately I don't know how to do this using server side language like PHP
You can use client storage. I have used llocalStoorage but you can use sessionStorage or localStorage as per your need. You can check the update
okay. I just need to digest the information.... I don't know what setIndex, localtstorage and lis[index || 0] means and do
|
0

Array of elements doesn't have to initialized two times. Using li class is a useless. Modern browsers (IE8+) can use querySelector() (querySelectorAll()) (similiar functionality to the jQuery selector). When document is ready we get array of links in #navmenu, we add listeners to them.

funclink function removes all classes from links and then sets class "current" to the element, that has triggered that function.

var slink; //prepare global scope var that will be filled with link elems
document.addEventListener("DOMContentLoaded", function() {//wait for document to be loaded
  slink = document.querySelectorAll("#navmenu li");//fill global var with array of link elems
  for (i = 0; i < slink.length; i++) {//add click listener to all link elems
    slink[i].addEventListener("click", function() {
      funclink(event);
    });
  }
});

function funclink(event) {
  for (i = 0; i < slink.length; i++)slink[i].className = ""; //remove all current classes
  event.currentTarget.className = "current"; //add current class to the element that triggered fnc
}
a {
  color: blue;
}

.current,
.current a {
  color: red;
}
<ul id="navmenu">
  <li class="current"><a href="#?module=home">Home</a></li>
  <li><a href="#?module=service">Call Service</a>
    <li><a class="a-left" href="#?module=rental">Rental</a></li>
    <li><a class="a-left" href="#?module=sales">Sales</a></li>
  </li>
</ul>

4 Comments

Please add explanation as to what and why have you changed. You are answering for readers'
@Rajesh I think it is pretty self explanatory - updated though... IMO i just made the code a bit cleaner and more effective. (I might be wrong)
Its not about self explanatory. A reader will have to go through your entire code and then reconcile with OP's code just to understand the difference. Hence explanation is very important. There are many people who do not have knowledge like you have and that makes obvious things confusing
@Rajesh you are right that i haven't taken newcommers in consideration. Judging from the OP code (if it's his own), i decided to make my answer short, but you are right it wouldn't be so obvious to less experienced coders.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.