0

I'm trying to enable onMouseOver and onMouseOut for all of my icons and replacing them with unique icons.

Originally I had this:

<img id="EEProfile" src="images/EEProfile.png" alt="Employee Profile" onMouseOver="mouseOver()" onMouseOut="mouseOut()">

External JS file:

function mouseOver() { document.getElementById("EEProfile").src = 'images/EEProfile_Hover.png'; }
function mouseOut() { document.getElementById("EEProfile").src = 'images/EEProfile.png'; }

There are a few issues with this:

  1. This method works on IE but for some reason on Chrome onMouseOut isn't working, so hover images are remaining.

  2. Requires some inline javascript. I'm trying to move towards eliminating all inline JS.

  3. Requires me to hardcode image paths for each and every image on the page.

Since all image paths are the same and follow the same naming convention, which is just

'images/ImageID.png' or 'images/ImageID_Hover.png'

I was hoping to implement something like this:

Pseudocode HTML:

<img id="EEProfile" src="images/EEProfile.png" alt="Employee Profile" onMouseOver="mouseOver(this.id)" OnMouseOut="mouseOut(this.id)">

Pseudocode JavaScript:

function mouseOver(id) { document.getElementById("id").src = 'images/id.png'; }
function mouseOut(id) { document.getElementById("id").src = 'images/id_Hover.png'; }

I want to pass over the ID of the image element to the mouseOver and mouseOut functions as a parameter, then use that ID's string literal in the image path so I don't have to hardcode every image's path. Is something like this possible? Is there a way to do this without inline JS?

I've considered using content:hover without JS but it isn't supported in IE.

moozin
  • 3
  • 2
  • Passing 'this' into the function in your html declaration like 'onMouseOver="mouseOver(this)"', then having function mouseOver(img){} will give you access to that img information and you will be able to get to the id. You can also leverage some JQuery and assign a class to your img's and do $('.img-class').each(function(){then bind mouse over and mouse out events to each individual img element} (or you can just do $('img') without assigning a class if you like). – Tyler Dahle Jun 30 '17 at 21:19

1 Answers1

1

I would give all the images you want to have the hover effect a specific class name. Then you can get all the element with that class and add event listeners for mouseover and mouseout. I used the current src to determine the new src. You could just as easily get the id with event.target.id and use that to build the src. You also could build the regular expression to match more than just .png files.

(function(window, document, undefined)
{
  var images = document.getElementsByClassName('hoverImage');
  for (var i = 0; i < images.length; i++) {
    images[i].addEventListener('mouseover', imageMouseOver, false);
    images[i].addEventListener('mouseout', imageMouseOut, false);
  }
})(window, window.document);


function imageMouseOver(event)
{
    event = event || window.event;

    var image = event.target;
    image.src = getNewImagePath(image.src);
    console.log(image);
}

function imageMouseOut(event)
{
  event = event || window.event;

  var image = event.target;
  image.src = getNewImagePath(image.src);
  console.log(image);
}

function getNewImagePath(path)
{
  var newPath;
  if (path.indexOf('_Hover') === -1) {
    newPath = path.replace('.png', '_Hover.png');
  } else {
    newPath = path.replace('_Hover', '');
  }
  
  return newPath;
}
.hoverImage {
  width: 50px;
  height: 50px;
}
<img id="1" src="images/1.png" alt="Employee Profile" class="hoverImage">
<img id="2" src="images/2.png" alt="Employee Profile" class="hoverImage">
<img id="3" src="images/3.png" alt="Employee Profile" class="hoverImage">
Russell
  • 476
  • 2
  • 10
  • This is exactly what I'm looking for but the only issue is the self-invoking function doesn't seem to be working. I still have to call mouseover and mouseout inline. I might be missing something obvious – moozin Jul 10 '17 at 14:53
  • I did assign class="hoverImage" to each image – moozin Jul 10 '17 at 15:26
  • @moozin If you use the self invoking function like I have above, you must ensure your javascript is being loading after the html. So if you're including the javascript file in the head instead of after the body then getElementsByClassName is not going to return the class list you're after because the img tags do not exist at that point. – Russell Jul 11 '17 at 00:14
  • That was exactly it. Thank you for your help. – moozin Jul 11 '17 at 18:19
  • What do you think of replacing: **newPath = path.replace('.png', '_Hover.png');** with **newPath = path.replace('.', '_Hover.');** This way it's not just limited to .png files. Of course then both the default image and the hover image must still be the same file type. – moozin Jul 25 '17 at 20:04
  • @moozin That will work, but you'll need to trim it down to just the file name otherwise you'll be replacing the '.' in your domain and any in the query string. https://stackoverflow.com/questions/29182283/javascript-onclick-get-image-name-without-path After you pull the image name out you will have to check for a query string if you use that as part of your cache busting. – Russell Jul 26 '17 at 01:31