444

I have a few images and their rollover images. Using jQuery, I want to show/hide the rollover image when the onmousemove/onmouseout event happen. All my image names follow the same pattern, like this:

Original Image: Image.gif

Rollover Image: Imageover.gif

I want to insert and remove the "over" portion of image source in the onmouseover and onmouseout event, respectively.

How can I do it using jQuery?

4
  • I wrote a small how-to with examples for beginners, Change image with JavaScript (or jQuery). There's also an example without using jQuery. Commented Aug 9, 2010 at 20:44
  • Change image on mouseover dotnetspeaks.com/DisplayArticle.aspx?ID=89 Commented Dec 7, 2010 at 8:15
  • 10
    Just what I'm looking for. Thanks for posting the Question! Commented Feb 18, 2011 at 6:40
  • I have a problem like this(My Question). The answer of this question is great but in IE9 every time that you goes over button, there is additional request for image and it is very bad. Is any body has better answer? Commented May 16, 2012 at 8:51

14 Answers 14

620

To set up on ready:

$(function() { $("img") .mouseover(function() { var src = $(this).attr("src").match(/[^\.]+/) + "over.gif"; $(this).attr("src", src); }) .mouseout(function() { var src = $(this).attr("src").replace("over.gif", ".gif"); $(this).attr("src", src); }); }); 

For those that use url image sources:

$(function() { $("img") .mouseover(function() { var src = $(this).attr("src"); var regex = /_normal.svg/gi; src = this.src.replace(regex,'_rollover.svg'); $(this).attr("src", src); }) .mouseout(function() { var src = $(this).attr("src"); var regex = /_rollover.svg/gi; src = this.src.replace(regex,'_normal.svg'); $(this).attr("src", src); }); }); 
Sign up to request clarification or add additional context in comments.

8 Comments

This doesnt work if the src is an absolute url with a . in it (like www.example.com)
This also doesn't work if you use a domain like www.over.com, or have over somewhere else in the URI.
may I suggest editing the final .replace with .replace("over.gif", ".gif");
Thanks for posting this. I hope you don't mind that I put this on my blog. My blog is like a "notebook" and it's my "go-to-thing" when I forget something.
It isnt necessary to use the ".match(/[^\.]+/)" method and with Regex. The ".replace(".gif", "over.gif") is enough for it to work.
|
114

I know you're asking about using jQuery, but you can achieve the same effect in browsers that have JavaScript turned off using CSS:

#element { width: 100px; /* width of image */ height: 200px; /* height of image */ background-image: url(/path/to/image.jpg); } #element:hover { background-image: url(/path/to/other_image.jpg); } 

There's a longer description here

Even better, however, is to use sprites: simple-css-image-rollover

6 Comments

yeah, but is little harder to do this on IMAGE elements :) Besides that, CSS mean the separation of content from presentation. If you do this, you join those things ;) You can't have this for a large site, right?
I agree with you about the css, but it seems the question author wanted a generic solution that applies to multiple images all at once.
This solution is the most preferable option, unless you are doing some effects. I was thinking the exact same thing +1
It is the best solution. To avoid waiting for the new image (network request) use a single image.jpg and play with background-position to show / hide the good one.
@kheraud Moving a single image is a good solution, but whether it's the best or not depends on the image size. For example, on slow internet, downloading two 1920px wide images in one gigantic file would take unacceptably long. For icons and small images though it works fine.
|
63

If you have more than one image and you need something generic that doesn't depend on a naming convention.

HTML

<img data-other-src="big-zebra.jpg" src="small-cat.jpg"> <img data-other-src="huge-elephant.jpg" src="white-mouse.jpg"> <img data-other-src="friendly-bear.jpg" src="penguin.jpg"> 

JavaScript

$('img').bind('mouseenter mouseleave', function() { $(this).attr({ src: $(this).attr('data-other-src') , 'data-other-src': $(this).attr('src') }) }); 

2 Comments

This was the one for me. Just remember to put the javascript inside a function to execute it ie when DOM ready "$(function(){ });"
Actually it triggers when the page is still loading, and when your mouse cursor is actually over the selector it replaces the url so then the effect is inverted
57
 /* Teaser image swap function */ $('img.swap').hover(function () { this.src = '/images/signup_big_hover.png'; }, function () { this.src = '/images/signup_big.png'; }); 

3 Comments

Keep in mind that going this way will mean that the user will see a pause on first hover while the browser fetches the image.
@Tyson Hate to hop onto the train late, but you can preload the images by either via Javascript or CSS
Doesn't work on Chrome 37 neither. $(this).attr("src", src) works fine.
26
+25

A generic solution that doesn't limit you to "this image" and "that image" only may be to add the 'onmouseover' and 'onmouseout' tags to the HTML code itself.

HTML

<img src="img1.jpg" onmouseover="swap('img2.jpg')" onmouseout="swap('img1.jpg')" /> 

JavaScript

function swap(newImg){ this.src = newImg; } 

Depending on your setup, maybe something like this would work better (and requires less HTML modification).

HTML

<img src="img1.jpg" id="ref1" /> <img src="img3.jpg" id="ref2" /> <img src="img5.jpg" id="ref3" /> 

JavaScript / jQuery

// Declare Arrays imgList = new Array(); imgList["ref1"] = new Array(); imgList["ref2"] = new Array(); imgList["ref3"] = new Array(); //Set values for each mouse state imgList["ref1"]["out"] = "img1.jpg"; imgList["ref1"]["over"] = "img2.jpg"; imgList["ref2"]["out"] = "img3.jpg"; imgList["ref2"]["over"] = "img4.jpg"; imgList["ref3"]["out"] = "img5.jpg"; imgList["ref3"]["over"] = "img6.jpg"; //Add the swapping functions $("img").mouseover(function(){ $(this).attr("src", imgList[ $(this).attr("id") ]["over"]); } $("img").mouseout(function(){ $(this).attr("src", imgList[ $(this).attr("id") ]["out"]); } 

Comments

21
$('img.over').each(function(){ var t=$(this); var src1= t.attr('src'); // initial src var newSrc = src1.substring(0, src1.lastIndexOf('.'));; // let's get file name without extension t.hover(function(){ $(this).attr('src', newSrc+ '-over.' + /[^.]+$/.exec(src1)); //last part is for extension }, function(){ $(this).attr('src', newSrc + '.' + /[^.]+$/.exec(src1)); //removing '-over' from the name }); }); 

You may want to change the class of images from first line. If you need more image classes (or different path) you may use

$('img.over, #container img, img.anotherOver').each(function(){ 

and so on.

It should work, I didn't test it :)

3 Comments

+1 Doh, forgot about the hover event helper! And nice suggestion about adding a class to the images - truly is a best practice :)
That's far better solution because it caches the old image source.
The negative part is, if the image is in the bottom of the page and there is 10-20 images then layout becomes weird.
13

I was hoping for an über one liner like:

$("img.screenshot").attr("src", $(this).replace("foo", "bar")); 

Comments

6

If the solution you are looking for is for an animated button, then the best you can do to improve in performance is the combination of sprites and CSS. A sprite is a huge image that contains all the images from your site (header, logo, buttons, and all decorations you have). Each image you have uses an HTTP request, and the more HTTP requests the more time it will take to load.

.buttonClass { width: 25px; height: 25px; background: url(Sprite.gif) -40px -500px; } .buttonClass:hover { width: 25px; height: 25px; background: url(Sprite.gif) -40px -525px; } 

The 0px 0px coordinates will be the left upper corner from your sprites.

But if you are developing some photo album with Ajax or something like that, then JavaScript (or any framework) is the best.

Have fun!

Comments

4
$('img').mouseover(function(){ var newSrc = $(this).attr("src").replace("image.gif", "imageover.gif"); $(this).attr("src", newSrc); }); $('img').mouseout(function(){ var newSrc = $(this).attr("src").replace("imageover.gif", "image.gif"); $(this).attr("src", newSrc); }); 

Comments

4

Whilst looking for a solution some time back, I found a similar script to the below, which after some tweaking I got working for me.

It handles two images, that almost always default to "off", where the mouse is off the image (image-example_off.jpg), and the occasional "on", where for the times the mouse is hovered, the required alternative image (image-example_on.jpg) is displayed.

<script type="text/javascript"> $(document).ready(function() { $("img", this).hover(swapImageIn, swapImageOut); function swapImageIn(e) { this.src = this.src.replace("_off", "_on"); } function swapImageOut (e) { this.src = this.src.replace("_on", "_off"); } }); </script> 

1 Comment

I realise that the above function would execute for all images within the DOM as it is currently coded. Supplying further context would make it focus the effect to specific img elements.
3
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>JQuery</title> <script src="jquery.js" type="text/javascript"> </script> <style type="text/css"> #box{ width: 68px; height: 27px; background: url(images/home1.gif); cursor: pointer; } </style> <script type="text/javascript"> $(function(){ $('#box').hover( function(){ $('#box').css('background', 'url(images/home2.gif)'); }); $('#box').mouseout( function(){ $('#box').css('background', 'url(images/home1.gif)'); }); }); </script> </head> <body> <div id="box" onclick="location.href='index.php';"></div> </body> </html> 

Comments

2

I've made something like the following code :)

It works only, when you have a second file named with _hover, for example, facebook.png and facebook_hover.png

$('#social').find('a').hover(function() { var target = $(this).find('img').attr('src'); //console.log(target); var newTarg = target.replace('.png', '_hover.png'); $(this).find('img').attr("src", newTarg); }, function() { var target = $(this).find('img').attr('src'); var newTarg = target.replace('_hover.png', '.png'); $(this).find('img').attr("src", newTarg); }); 

Comments

1
<img src="img1.jpg" data-swap="img2.jpg"/> img = { init: function() { $('img').on('mouseover', img.swap); $('img').on('mouseover', img.swap); }, swap: function() { var tmp = $(this).data('swap'); $(this).attr('data-swap', $(this).attr('src')); $(this).attr('str', tmp); } } img.init(); 

Comments

1

Adapted from Richard Ayotte's code - To target an img in a ul/li list (found via wrapper div class here), something like this:

$('div.navlist li').bind('mouseenter mouseleave', function() { $(this).find('img').attr({ src: $(this).find('img').attr('data-alt-src'), 'data-alt-src':$(this).find('img').attr('src') } ); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.