Home > Enterprise >  Swapping an input image on hover
Swapping an input image on hover

Time:11-17

I am using an image for an input (button) within a form on my website, and would like to swap the image on hover.

The following code works fine in a stand alone demo. The images swap nicely.

However... when I integrate this code into the rest of the form code, it fails.

I am guessing it is because the script calls for 'getElementsByTagName('input')' with the tag name being 'input'.

Therefore... perhaps because the form contains other 'inputs', the function targets the other inputs as well, and simply dies??????

Is there a way to execute this same function, and target the specific input without using the 'getElementsByTagName('input')', or by tweaking it some way?

Any help would be appreciated.

Thank you,

Maddison

HTML

<!DOCTYPE html>

<head>

<title>Image Swap Test</title>

</head>

<body>

<input type="image" src="/images/image1.png" data-alt-image="/images/image2.png" />


<script>

var inputs = document.getElementsByTagName('input');

for (var i = 0, len = inputs.length; i < len; i  ) {
input = inputs[i];
input.onmouseover = function(){
    this.setAttribute('data-orig-image',this.getAttribute('src'));
    this.src = this.getAttribute('data-alt-image');
};
input.onmouseout = function(){
    this.src = this.getAttribute('data-orig-image');
};
}

</script>


</body>

</html>

CodePudding user response:

If you use querySelectorAll, then you can use CSS selectors - this way, you can narrow down your list however you like (limit is CSS selectors only).

In the snippet below I broke up your code a bit, but the main point (regarding your question) is that with querySelectorAll I could narrow down the input list with a type. This way, if really a clash is the problem in your context, the problem should be solved (of course, you could be adding a class, or just "filter" for the data-alt-image).

Also, by updating the iterator function (for...i -> inputs.forEach), it works nicely with multiple inputs.

const ORIG_URL_ATTR = 'src'
const ALT_URL_ATTR = 'data-alt-image'

const switchImageUrls = ([curr, alt]) => [alt, curr]

const getImageUrls = (input) => [input.getAttribute(ORIG_URL_ATTR), input.getAttribute(ALT_URL_ATTR)]

const setImageUrls = (input) => ([curr, alt]) => {
  input.setAttribute(ORIG_URL_ATTR, curr)
  input.setAttribute(ALT_URL_ATTR, alt)
}

const handleMouseEvent = (input) => {
  setImageUrls(input)(switchImageUrls(getImageUrls(input)))
}

const setEventHandlers = (input) => {
  input.onmouseover = () => handleMouseEvent(input);
  input.onmouseout = () => handleMouseEvent(input);
}

const inputs = document.querySelectorAll('input[type="image"]');

inputs.forEach(setEventHandlers)
<input type="image" src="https://via.placeholder.com/150/0000FF/808080?text=orig1" data-alt-image="https://via.placeholder.com/150?text=alt1" />
<input type="image" src="https://via.placeholder.com/150/0000FF/808080?text=orig2" data-alt-image="https://via.placeholder.com/150?text=alt2" />

CodePudding user response:

Here is a jQuery solution, short & sweet:

function swapImage(elem) {
  let src = elem.attr('src');
  let alt = elem.data('alt');
  elem.attr('src', alt);
  elem.data('alt', src);
}

$('document').ready(function() {
  $('input[type="image"]').hover(function () {
    swapImage($(this));
  }, function () {
    swapImage($(this));
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="image" src="https://via.placeholder.com/150/0000FF/808080?text=orig1" data-alt="https://via.placeholder.com/150?text=alt1" />
<input type="image" src="https://via.placeholder.com/150/0000FF/808080?text=orig2" data-alt="https://via.placeholder.com/150?text=alt2" />

  • Related