Reputation: 1280
For this particular challenge I am required to toggle membership of an already created class for all <li>
elements in two given lists (at the same time). If a <li>
element in either list is not currently assigned the class, it is assigned the class; if a <li>
element in either list is currently assigned the class, the class is removed. Everytime a button is clicked, the class is added and removed (e.g on first click, the class could be added - then on second click, the class could be removed, etc).
I have been asked to do this particular task specifically in normal JavaScript. While I know that jQuery would be the easier option, I have been asked to undertake this task with just normal JavaScript.
When I press the button, the css class is being applied as expected (here, the font-family, font-size, and the font-stretch properties are being altered); however, when I click on the button the second time, nothing changes (e.g the class being removed), and everything going back to normal.
If anyone can point me towards a non-jQuery way of adjusting my current code, let me know.
Thanks for your help :).
Here is the relevant HTML, CSS, and JavaScript for this task:
HTML:
<ul id="newZealandList">
<li>Auckland</li>
<li>Wellington</li>
<li>Christchurch</li>
<li>Tauranga</li>
<li>Dunedin</li>
</ul>
<ul id="usaList">
<li>Los Angeles</li>
<li>San Francisco</li>
<li>San Diego</li>
<li>Denver</li>
<li>Boulder</li>
</ul>
<button id="modifyListsToggle">Change Lists - Toggle</button>
CSS:
.modifyListElements{
font-family:"Comic Sans MS", cursive;
font-size:24px;
font-stretch:extra-expanded;
}
JavaScript
var newZealandListItems = document.getElementById("newZealandList").getElementsByTagName("li");
var usaListItems = document.getElementById("usaList").getElementsByTagName("li");
function addClass(obj)
{
obj.className="modifyListElements";
}
function removeClass(obj)
{
obj.className = "";
}
function toggleClass()
{
for (var i = 0; i < newZealandListItems.length; i++) {
if(i.className != "modifyListElements") {
//newZealandListItems[i].className = "modifyListElements";
addClass(newZealandListItems[i]);
}
else
{
//newZealandListItems[i].className = "";
removeClass(newZealandListItems[i]);
}
}
for (var i = 0; i < usaListItems.length; i++) {
if(i.className != "modifyListElements") {
//usaListItems[i].className = "modifyListElements";
addClass(usaListItems[i]);
}
else
{
//usaListItems[i].className = "";
removeClass(usaListItems[i]);
}
}
}
var modifyListsToggle = document.getElementById("modifyListsToggle");
modifyListsToggle.onclick = toggleClass;
Upvotes: 2
Views: 442
Reputation: 7134
A small bug in your code checking classname . I modified your code it working fine . Please check it
var newZealandListItems = document.getElementById("newZealandList").getElementsByTagName("li");
var usaListItems = document.getElementById("usaList").getElementsByTagName("li");
function addClass(obj)
{
obj.className="modifyListElements";
}
function removeClass(obj)
{
obj.className = "";
console.log(obj.className);
}
function toggleClass()
{
for (var i = 0; i < newZealandListItems.length; i++) {
var item = newZealandListItems[i];
if(item.className != "modifyListElements") {
//newZealandListItems[i].className = "modifyListElements";
addClass(item);
}
else
{
//newZealandListItems[i].className = "";
removeClass(item);
}
}
for (var i = 0; i < usaListItems.length; i++) {
var item = usaListItems[i];
if(item.className != "modifyListElements") {
//usaListItems[i].className = "modifyListElements";
addClass(item);
}
else
{
//usaListItems[i].className = "";
removeClass(item);
}
}
}
var modifyListsToggle = document.getElementById("modifyListsToggle");
modifyListsToggle.onclick = toggleClass;
Upvotes: 1
Reputation: 37179
The easiest way you could do this (although IE support is problematic) is like this:
var btn = document.getElementById('modifyListsToggle'),
lists = document.querySelectorAll('ul');
btn.addEventListener('click', function(e) {
for(var i = 0; i < lists.length; i++) {
var items = lists[i].querySelectorAll('li');
for(var j = 0; j < items.length; j++) {
items[j].classList.toggle('modifyListElements');
}
}
}, false);
querySelectorAll()
is only supported by IE8+addEventListener()
is only supported by IE9+classList
is only supported by IE10Upvotes: 0
Reputation: 4921
Issue is here
for (var i = 0; i < newZealandListItems.length; i++) {
if(i.className != "modifyListElements") {
//con....
and here
for (var i = 0; i < usaListItems.length; i++) {
if(i.className != "modifyListElements") {
//con....
i is just the loop counter variable, you need to use it access the item at that index so should be
for (var i = 0; i < newZealandListItems.length; i++) {
if (newZealandListItems[i].className != "modifyListElements") {
//con..
and
for (var i = 0; i < usaListItems.length; i++) {
if (usaListItems[i].className != "modifyListElements") {
//con..
On another note, this code will potentially have an issue if multiple classes are used, as the .className property will return all the classes on an element. If that may be an issue in the future, I would pursue using a className.replace('modifyListElements','') for remove (that way it will only remove that class and not other ones if there). And the tests for one class on className will also not work if multiple classes are there. In this case pursuing a test and then a .replace would probably be the solution.
Upvotes: 2