0

I do work with w3.css framework. Have a slide with caption in the middle. I want to use js i.e when I mouseOver caption color changes, when I mouseout background color gets back to its previous position. I have three same div blocks (HTML code shown below):

<div class="w3-display-container mySlides">
  <img src="yellow.png" style="width:100%">
  <div class="w3-display-middle w3-large w3-container w3-padding-16 w3-black hover"> 
      HOVER TO MAKE ME TEAL
  </div>
</div>

<div class="w3-display-container mySlides">
  <img src="yellow.png" style="width:100%">
  <div class="w3-display-middle w3-large w3-container w3-padding-16 w3-black hover">
      HOVER TO MAKE ME TEAL
  </div>
</div>

<div class="w3-display-container mySlides">
  <img src="yellow.png" style="width:100%">
  <div class="w3-display-middle w3-large w3-container w3-padding-16 w3-black hover">
      HOVER TO MAKE ME TEAL
  </div>
</div>

My javascript has some issue, but not sure what is wrong. (I am amateur javascript self-taught). My JS code (shown below):

document.getElementsByClassName("hover").addEventListener("mouseover", mouseOver);
document.getElementsByClassName("hover").addEventListener("mouseout", mouseOut);

var classChanged = document.getElementsByClassName("hover");
for (z = 0; classChanged.length; z++) { /* Iteration */
classChanged[z].style.backgroundColor = this; /* How to bind two functions shown below ?!*/

function mouseOver(classChanged) { /* binding with keyword THIS? */ 
classChanged.classList.remove("w3-black");
classChanged.classList.add("w3-teal");
}

function mouseOut(classChanged) { /* binding with keyword THIS? */ 
classChanged.classList.remove("w3-teal");
classChanged.classList.add("w3-black");
}

My mission is to apply functions to all three div blocks sharing the same class="... hover". Any help would be appreciated. Thank you. p.s I was managed to use getElementById() method to trigger first HTML block functions in order to change background color. Still only one. :'(

projektorius96
  • 114
  • 2
  • 10
  • 1
    I think you're on the right track - the answer to "how does it handle iteration" is "it doesn't". You will need to do the iteration over the elements returned by `getElementsByClassName` yourself. – Bergi Apr 10 '18 at 20:20
  • @Bergi Any educational example or reference to? Thank you. – projektorius96 Apr 10 '18 at 20:23
  • 2
    @WebMasteris Check this out: https://stackoverflow.com/a/19655662/1913729 – blex Apr 10 '18 at 20:28
  • 1
    @blex Sorry, I didn't have a full look through my answer, and I feel it's confusing as well as wrong. Hey, don't judge me by this one. Look at my [previous answers](https://stackoverflow.com/users/462627/praveen-kumar?tab=answers) and they all are better. `:)` Thanks for the heads up. – Praveen Kumar Purushothaman Apr 10 '18 at 20:41
  • 1
    @PraveenKumar I'm not judging you (I've seen great answers from you in the past, and I know you're awesome). I'm just trying to help everyone by mentioning a couple of mistakes that I feel could add confusion. Sorry if my comment sounded harsh :) – blex Apr 10 '18 at 20:42

2 Answers2

1

getElementsByClassname will return an iterable node list (array-like object) from there you can iterate through the list using a for loop to apply any event listeners you may need.

If you are sure that you only need to support newer browsers this works you can also use forEach to iterate through the node list, but to pull the quote from MDN:

Although NodeList is not an Array, it is possible to iterate on it using forEach(). It can also be converted to an Array using Array.from().

However some older browsers have not yet implemented NodeList.forEach() nor Array.from(). But those limitations can be circumvented by using Array.prototype.forEach() (more in this document).

(function() {
  
  // Get your node list
  const elements = document.getElementsByClassName('hover')
  
  // iterate through using a loop
  for (let i = 0, len = elements.length; i < len; i++) {
    // add mouseover event to given element index
    elements[i].addEventListener('mouseover', e => { 
      e.target.classList.remove('w3-black');
      e.target.classList.add('w3-teal');
    });
    // add mouseout event to given element index
    elements[i].addEventListener('mouseout', e => { 
      e.target.classList.remove('w3-teal');
      e.target.classList.add('w3-black');
    });
  }
 
})();
.w3-teal { background-color: teal; }
.w3-black { background-color: black; }
<div class="w3-display-container mySlides">
  <img src="yellow.png" style="width:100%">
  <div class="w3-display-middle w3-large w3-container w3-padding-16 w3-black hover"> 
      HOVER TO MAKE ME TEAL
  </div>
</div>

<div class="w3-display-container mySlides">
  <img src="yellow.png" style="width:100%">
  <div class="w3-display-middle w3-large w3-container w3-padding-16 w3-black hover">
      HOVER TO MAKE ME TEAL
  </div>
</div>

<div class="w3-display-container mySlides">
  <img src="yellow.png" style="width:100%">
  <div class="w3-display-middle w3-large w3-container w3-padding-16 w3-black hover">
      HOVER TO MAKE ME TEAL
  </div>
</div>
D Lowther
  • 1,609
  • 1
  • 9
  • 16
1
var hover = document.querySelectorAll('.hover');

hover.forEach(e => e.addEventListener("mouseover", () => mouseOver(e)));
hover.forEach(e => e.addEventListener("mouseout", () => mouseOut(e)));

function mouseOver(e) {
    e.classList.remove("w3-black");
    e.classList.add("w3-teal");
}

function mouseOut(e) {
    e.classList.remove("w3-teal");
    e.classList.add("w3-black");
}

DEMO: https://jsfiddle.net/Lahcj936/

Ivan
  • 1,967
  • 4
  • 34
  • 60