使用jQuery在鼠标悬停时更改图像源

445

我有几张图片以及它们的悬停图片。使用jQuery,我想在发生onmousemove/onmouseout事件时显示/隐藏悬停图片。所有我的图像名称都遵循相同的模式,如下:

原始图片:Image.gif

悬停图片:Imageover.gif

我想在onmouseover和onmouseout事件中分别插入和删除图像源中的“over”部分。

我该如何使用jQuery实现?


我为初学者写了一个带有示例的小型入门指南,*使用JavaScript(或jQuery)更改图像*。还有一个不使用jQuery的示例。 - gothy
鼠标悬停时更改图像 http://www.dotnetspeaks.com/DisplayArticle.aspx?ID=89 - Sumit
10
正是我所需要的。感谢您发布这个问题! - Samuel Meddows
我有一个类似这样的问题(我的问题). 这个问题的答案很好,但在IE9中,每次你经过按钮时,都会有额外的图片请求,这非常糟糕。有没有更好的答案? - Iman
14个回答

621

为了设置“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);
        });
});

对于那些使用URL图片来源的人:

$(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);

            });
    });

7
如果src是一个包含"."的绝对URL(如www.example.com),则此方法无效。 - Kieran Andrews
32
可以建议将最后一个 ".replace" 修改为 ".replace("over.gif", ".gif")。 - Nathan Koop
2
谢谢您发布这篇文章。希望您不介意我在我的博客上分享它。我的博客就像一个“笔记本”,当我忘记某些东西时,它是我的“必备品”。 - wenbert
1
不必使用“.match(/ [^ \。] + /)”方法和正则表达式。 “.replace(“.gif”,“over.gif”)就足够让它工作了。 - Navigatron
显示剩余3条评论

114

我知道你在问如何使用jQuery,但你可以通过CSS在浏览器禁用JavaScript时达到相同的效果:

#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);
}

这里有一个更详细的描述

然而更好的方法是使用精灵图:simple-css-image-rollover


1
是的,但在图像元素上做这件事有点困难 :) 除此之外,CSS意味着内容与表现的分离。如果你这样做,就会将它们结合起来 ;) 对于大型网站,你不能这样做,对吧? - Ionuț Staicu
我同意你对于CSS的看法,但似乎问题的提问者想要一个通用的解决方案,可以一次应用于多个图片。 - Jarrod Dixon
确实,但我猜这不是一遍又一遍重复的相同图像 :) 我是一个CSS专家,但这次...不是最好的选择 :) - Ionuț Staicu
9
除非你需要一些特效,否则这个解决方案是最优选项。我也是这么想的 +1。 - Angel.King.47
6
最佳解决方案是,为了避免等待新的图片(网络请求),使用单个image.jpg,并通过调整background-position来显示/隐藏需要展示的图片。 - kheraud
2
@kheraud 移动单个图像是一个不错的解决方案,但最佳方案是否取决于图像大小。例如,在慢的互联网上,下载两张1920像素宽的图片在一个巨大的文件中将花费不可接受的长时间。但对于图标和小图像,这种方法效果良好。 - DACrosby

63
如果您有多张图片,需要一些通用的方法而不依赖于命名约定。
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') 
    })
});

1
这对我来说是最好的选择。只需记得将JavaScript放在一个函数内执行,即当DOM准备就绪时。“$(function(){ });” - Mischa
实际上,它会在页面仍在加载时触发,并且当您的鼠标光标实际上悬停在选择器上时,它会替换URL,因此效果是反转的。 - Mike

57
    /* Teaser image swap function */
    $('img.swap').hover(function () {
        this.src = '/images/signup_big_hover.png';
    }, function () {
        this.src = '/images/signup_big.png';
    });

4
请记住,选择这种方式意味着用户在第一次悬停时会看到一个暂停,因为浏览器正在获取图像。 - Tyson
1
@Tyson 很抱歉晚来一步,但你可以通过Javascript或者CSS预加载图片。 - cbr
在Chrome 37上也无法工作。 $(this).attr("src", src)运行良好。 - Le Droid

26
一种通用的解决方案,不仅限于“这个图像”和“那个图像”,可能是将“onmouseover”和“onmouseout”标签添加到HTML代码本身中。
<img src="img1.jpg" onmouseover="swap('img2.jpg')" onmouseout="swap('img1.jpg')" />

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

根据您的设置,也许像这样做会更好(并且需要较少的HTML修改)。
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"]);
  }

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
    });
});

您可能需要更改首行图像的类。如果需要更多的图片类(或不同的路径),可以使用

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

它应该可以工作,我没有测试它 :)。之类的。

2
+1 哦,忘记了悬停事件助手!关于向图像添加类的建议很好 - 确实是最佳实践 :) - Jarrod Dixon
1
这是更好的解决方案,因为它缓存了旧的图像源。 - trante
负面的一点是,如果图像位于页面底部并且有10-20个图像,则布局会变得奇怪。 - trante

13

我希望有一个像超级一行代码那样的东西:

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

6

如果您正在寻找的解决方案是用于动画按钮,那么您可以通过精灵图和CSS的结合来提高性能。 精灵图是一个包含站点上所有图像(标题、徽标、按钮以及所有装饰)的巨大图像。 每个图像都使用一个HTTP请求,HTTP请求越多,加载时间就越长。

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

0px 0px 坐标将是您的精灵左上角。

但如果您正在使用Ajax或类似工具开发相册,那么JavaScript(或任何框架)是最好的选择。

玩得开心!


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); 
});

4
在一段时间前,我在寻找解决方案时,找到了下面类似的脚本,经过一些调整后,我让它为我工作起来了。
它处理两张几乎总是默认为“关闭”状态的图片,当鼠标离开图片时显示(image-example_off.jpg),很少出现的“打开”状态,在鼠标悬停时,显示所需的替代图像(image-example_on.jpg)。
<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>

我意识到当前编码的上述函数将适用于 DOM 中的所有图像。提供更多上下文将使其聚焦于特定的 img 元素。 - Kristopher Rout

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接