iamflee_
iamflee_

Reputation: 27

Unable to change the class of a div using JavaScript

So I got into JavaScript and tried setting up the following scenario:

I have 2 Buttons on my Site (IDs are buttonWebdev and buttonUXUI), which should trigger an Action when they are hovered upon. If buttonWebdev is hovered upon, it should hide all p', h3's and imgs with the class "classWeb". I wrote this code to do it, but it doesn't work:

HTML:

<h3 class="classWeb">Editierbare Inhalte</h3>
  <p class="classWeb">Test</p>
<button class="buttonImg" id="buttonWebdev"><img src="./img/buttonWebdev.png" /></button>
<script type="text/javascript">
var button = document.getElementById('buttonWebdev');
var classWeb = document.getElementsByClassName('classWeb');
button.onmouseover = function() {
  classWeb.className = 'webdev';

}

CSS:

.classWeb.webdev {
  display: none;
}

Upvotes: 1

Views: 56

Answers (3)

Ry-
Ry-

Reputation: 224867

First, since there can be more than one element with a given class on a page, getElementsByClassName returns a list of elements instead of a single element. You’ll need to perform your action on every element of that list, with a for…of loop, for example:

for (let element of classWeb) {
    element.className = 'webdev';
}

(for…of is relatively new, though, so you might have to use a regular for loop depending on your target browsers.)

After fixing this, you’ll run into another problem. When you assign to className like that, you’re setting the entire list of classes on an object. If the list of classes is 'webdev', it no longer includes 'classWeb'. Modern browsers support an API to add a class without affecting the rest:

for (let element of classWeb) {
    element.classList.add('webdev');
}

The way to diagnose these sorts of problems is by opening up your browser’s developer tools, looking for JavaScript errors in the console, and looking at the state of the elements you’re trying to affect in the document tree.

Upvotes: 4

mihelcic
mihelcic

Reputation: 66

Firstly, the

document.getElementsByClassName('classWeb');

will give you a LIVE list of all the matched elements. That means that when you reassign the class like so:

classWeb[0].className = 'webdev';

the element will be removed from the list, as it no longer corresponds to the original command which was to find all elements with a specific class (which you overrode with 'webdev').

An easier and more friendly api is querySelectorAll which mimics the jQuery selector (which uses css selectors to find elements, thats why there is a # for an id and a . for a class name). The example below shows, how to use it.

var button = document.querySelector('#buttonWebdev');
var classWeb = document.querySelectorAll('.classWeb');

button.onmouseenter = function() {
    for (var i = 0; i < classWeb.length; i++) {
      classWeb[i].className = 'webdev';
    }
}

ps. The querySelectorAll is not a live list, so items will not disappear after you change their class.

ps2. Use onmousenter instead of onmouseover as the onmouseenter is only called when the mouse starts hovering over an element, while onmouseover will be called on every mouse move over the element (even if already hovering).

Good luck!

Upvotes: 0

vinayakj
vinayakj

Reputation: 5681

  1. document.getElementsByClassName('classWeb'); this gives collection & to add classes you need to iterate over them & then apply classes.

  2. classWeb[0].className = 'webdev'; would reset class

either use classWeb[i].className += ' webdev'; or classWeb[i].classList.add('webdev');

See below working example

var button = document.getElementById('buttonWebdev');
var classWeb = document.getElementsByClassName('classWeb');
button.onmouseover = function() {
  for (var i = 0; i < classWeb.length; i++)
    classWeb[i].className += ' webdev';
}
.classWeb.webdev {
  display: none;
}
<h3 class="classWeb">Editierbare Inhalte</h3>
<p class="classWeb">Test</p>
<button class="buttonImg" id="buttonWebdev">hover over me</button>

Upvotes: 0

Related Questions