Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Tyler Durden
Tyler Durden
2,406 Points

JavaScrip EventListener mouseover bug?

Hi, I was trying to implement some of the javascript knowledge I learned from treeHouse to my website and I was experiencing a "hover" bug for a script I wrote. Basically, upon hovering over an image on the page, a div with text inside should appear (display: block). At all other times, the div is set to display :none.

You can see the bug yourself if you go to http://alpizano.com/projects.php and hover over any of the divs and you will see the "learn more" flash in/flash out rapidly

Here is the JS:

var panels = document.getElementsByClassName('hoverButton');

for(let i=0; i<panels.length; i++) {
panels[i].addEventListener("mouseover", moveIt);
panels[i].addEventListener("mouseleave", dontMoveIt);
}

function moveIt() {
  var blah = this.parentElement.nextElementSibling;
  blah.style.display = 'block';
}

function dontMoveIt () {
  var blah = this.parentElement.nextElementSibling;
  blah.style.display = 'none';
}

and then the HTML :

<div class="box-1">
     <a class="blue" href="student_marks.php">
          <img class="hoverButton sgm" src="assets/images/room.png">
     </a>
        <div class="button-props">Learn more</div>
        <div class="text-info">Student Grade Manager</div>
 </div>

if you go to my

2 Answers

Steven Parker
Steven Parker
231,007 Points

You should be aware that "localhost" is your own computer, nobody can connect to that URL except for you.

However, from the provided code I can see that depending on the layout (the CSS is not shown here) and/or the scroll position of the window, it's possible to place the cursor in a position that will cause it to be over the image when the message is not displayed, but to be outside of the image when the message is displayed. This would cause the "flashing" behavior as the cursor keeps triggering the opposite condition.

To fix this, adjust your layout so that the action won't move the triggering element from under the cursor.

A non-CSS fix would be to use the "visibility" property instead of "display". Setting it to "hidden" will conceal an element but not move the others around it.

Tyler Durden
Tyler Durden
2,406 Points

LOL, it was a typo, damnnit. Here http://alpizano.com/projects.php

I ended editing the javascript so the button pops up AND stays but it looks like when the button "learn more" pops up, the image behind it is NOT being detected anymore (when the mouse is hovered on the div box for the 'learn more ' button). Is this because when the button pops up, it overlaps the image on TOP of it, and when the mouse is at that point, it is not detected as part of the image because its behind the button?

let imgs = document.getElementsByClassName('hoverButton');
let bttns = document.getElementsByClassName('button-props');

for(let i=0; i<imgs.length; i++) {
imgs[i].addEventListener("mouseover", moveIt);
bttns[i].addEventListener("mouseover", dontDissa);
bttns[i].addEventListener("mouseleave", dissa);
imgs[i].addEventListener("mouseleave", dontMoveIt);
}


/*
for(let k=0; k<bttns.length; k++) {
  bttns[k].addEventListener("mouseover", stay);
  bttns[k].addEventListener("mouseleave", go);
}*/



function moveIt() {
  //var blah = this.parentElement.nextElementSibling;
  var bttn = this.nextElementSibling;
  //bttn.style.display = 'block';
  bttn.style.visibility = 'visible';
}

function dontMoveIt () {
  //var blah = this.parentElement.nextElementSibling;
  var bttn = this.nextElementSibling;
  //bttn.style.display = 'none';
  bttn.style.visibility = 'hidden';
}

function dontDissa() {
  var img = this.previousElementSibling;
  //this.style.display = 'block';
  this.style.visibility = 'visible'; //make button stay when hovered on img
  //img.style.opacity = 0.5;
}


function dissa() {
  var img = this.previousElementSibling;
  //img.style.opacity= 0.5;
}
Steven Parker
Steven Parker
231,007 Points

I'm not sure what you mean by "behind the button". Based on the code shown here, what you are calling a "button" is actually just a "div" and it appears below the image. I suppose there must be some CSS code involved that you didn't show here.

It looks like you've changed the traversal and complicated things with extra event handlers. But if you want the invisible portion to show while you hover over any of the parts, just place the handlers on the "box" divs and adjust the traversal accordingliy:

let imgs = document.getElementsByClassName("hoverButton");

for (let i = 0; i < imgs.length; i++) {
  let box = imgs[i].parentElement.parentElement;
  box.addEventListener("mouseover",  showIt);
  box.addEventListener("mouseleave", hideIt);
  hideIt.call(box);    // hide items initially
}

function showIt() {
  let bttn = this.firstElementChild.nextElementSibling;
  bttn.style.visibility = "visible";
}

function hideIt() {
  let bttn = this.firstElementChild.nextElementSibling;
  bttn.style.visibility = "hidden";
}

This is also another way to resolve the "flashing" so you could go back to using display if you prefer.

Tyler Durden
Tyler Durden
2,406 Points

I fixed it this way:

let imgs = document.getElementsByClassName('hoverButton');
let bttns = document.getElementsByClassName('button-props');

for(let i=0; i<imgs.length; i++) {
imgs[i].addEventListener("mouseover", moveIt);
imgs[i].addEventListener("mouseleave", dontMoveIt);
bttns[i].addEventListener("mouseover", dontDissa);
}

function moveIt() {
  var bttn = this.nextElementSibling;
  this.style.opacity = 0.5;
  bttn.style.visibility = 'visible';
}

function dontMoveIt () {
  this.style.opacity = 1;
  var bttn = this.nextElementSibling;
  bttn.style.visibility = 'hidden';
}

function dontDissa() {
  var img = this.previousElementSibling;
  this.style.visibility = 'visible'; //make button stay when hovered on img
  img.style.opacity = 0.5;
}

I only called it " button" because it resembles a button (logically) and by "behind" I meant that it was pretty clear that the div (or button) was flashing because the mouse cursor was being detected as "OFF" the image when it hover over the IMAGE but then move to the div/button surface area.

I simply removed some CSS hover opacity code I had lingering around and let the events handle that hover effect And added a condition in the JS that when I hover the image and move to the div (or button), it force displays as "block".

I didn't have a chance to try your code ,but thanks for your input!

Steven Parker
Steven Parker
231,007 Points

CSS might actually be a better way to implement the functionality you have in mind, my JavaScript suggestions were based on the code shown here.