最佳的图片交互效果实现方式是什么?

5

当鼠标悬停时,我希望我的主标志更换。

我知道有几种实现方法,并想知道最稳定、兼容性最好、效率最高且设置最简单的方法是什么。

我找到的一些方法包括:

  • 使用Javascript(jQuery)替换“src”属性。
  • 使用背景和“hover”的CSS

还有其他方法吗?哪个最好?


我觉得这个应该被放到维基上。这是一个非常普遍的问题,对于中级前端开发人员来说,知道如何回答这个问题是很重要的。此外,它要求针对某些情况下有许多解决方案的问题提供“最佳”解决方案。 - Steven
8个回答

10

底线

对于包含内容的图片,您应该在HTML标记中使用src。对于需要滚动效果的图片,您可以使用JavaScript并将滚动图片放在属性中。

对于不包含内容的UI元素,特别是在整个网站或多处出现的元素上,直接使用CSS解决方案是最好的选择(这样您就不必在每次调用时重新声明图像位置)。在CSS解决方案中,精灵图(sprites)是最佳选择,因为它们不需要预加载开销。

JavaScript解决方案

HTML:

<img src="/img/one.jpg" data-rollover="/img/two.jpg" />

在jQuery中:

$(function(){
  $('img.rollover').hover(function(){
    var e = $(this);
    e.data('originalSrc', e.attr('src'));
    e.attr('src', e.attr('data-rollover'));
  }, function(){
    var e = $(this);
    e.attr('src', e.data('originalSrc'));
  }); /* a preloader could easily go here too */
});

示例实现:http://jsfiddle.net/dtPRM/1/

优点:易于实现;逻辑清晰;一旦设置好库,就可以最小化额外标记来处理。

缺点:需要JavaScript,并要加载jQuery库的开销。

可能是最佳选择。如果用户使用与悬停相关的浏览器(很可能是这种情况),他们具有运行此选项所需的JavaScript功能。那些出于某种原因故意关闭JavaScript的人会收到一个 <noscript> 的提示说明他们可能无法获得完整的功能集。

CSS解决方案:最佳

HTML:

<div id="img1" />

CSS:

div#img1 {
  height: 400px;
  width: 300px;
  background: url('http://dummyimage.com/600x400/000/fff') no-repeat top left;}
div#img1:hover {
  background-position: top right;}

示例实现:http://jsfiddle.net/dtPRM/5/

个人认为,对于包含内容的图片而言,这比使用CSS和两张背景图片的解决方案更糟糕。你将HTML标记从显示的语义值中分离出来。

但是,如果您使用没有内容的图像(如UI元素),则我认为这是最佳解决方案。

CSS解决方案:也可以

另外还有一种CSS选项可用,它不涉及背景图像(如果您想在HTML中使用图像标记,例如对于语义上有意义的图像,则会优先考虑这种解决方案)。

<div class="rollover">
  <img class="rollover" src="http://dummyimage.com/600x400/000/fff" />
  <img class="" src="http://dummyimage.com/600x400/fff/000" />
</div>

CSS(我在这里使用:not伪选择器,但避免使用它也很容易;我还认为我语义上颠倒了类名):

div.rollover img:not(.rollover) {display: none;}
div.rollover:hover img:not(.rollover) {display: inline;}
div.rollover:hover img.rollover {display: none;}

示例实现:http://jsfiddle.net/dtPRM/2/

优点:与以前在样式表中放置所有信息的CSS解决方案相比,从语义上讲更加明智。

缺点:需要多余的标记。

评论:这个可能会根据浏览器是否调用而自动预加载。

底线:如果选项(1)不可用,因为您绝对需要IE2兼容性或非JS支持,则是一个不错的备选方案。

CSS不是解决方案:请远离

我之所以提及这一点,是因为你在问题中提到了它。 我不会使用它。

HTML:

<div id="img1" />

CSS:

div#img1 {
  height: 400px;
  width: 600px;
  background: url('http://dummyimage.com/600x400/000/fff') no-repeat top left;}
div#img1:hover {
  background-image: url('http://dummyimage.com/600x400/fff/000');}

示例实现: http://jsfiddle.net/dtPRM/4/

优点: 兼容性广泛; 您只需要支持背景图像和悬停功能。

缺点: 在CSS中放置图像和对其进行集中管理在语义上可能会有些奇怪,且会使未来的修改更加困难。尽管如此,如果您需要创建一个需要交互效果的图像,那么很可能这是一个非内容图像(例如UI元素),在这种情况下,使用CSS也许比普通图像在语义上更合适。请参见下面关于精灵图的注释。

其他缺点: 您必须小心声明图像的高度和宽度(这是一个很好的做法,但当您只想快速完成任务时可能会变得繁琐)。在移动浏览器上查看时,可能会处理CSS背景图像的方式与预期不同。

更多缺点: 如果您想在其上层添加预加载器,则需要使用JavaScript并选择可交互的元素,这样做的速度可能与直接使用JavaScript相当。

底线: 不要将此用于内容图像。如果必须避免使用JavaScript,请对UI元素使用精灵图,并对语义上有意义的图像使用其他解决方案。


1
从 jQuery 1.4.3 开始,您可以使用 .data() 访问 HTML5 data- 属性。http://api.jquery.com/data - alexia
1
感谢这篇好的概述。我使用了“CSS解决方案:也可以”,因为它易于编辑(两个URL在一个地方)并且与_retina.js_兼容(为所有img标签切换高分辨率图像)。但是,事实证明,这种解决方案在触摸设备上存在错误:如果悬停图像被链接,当轻敲时链接并不总是被跟踪。因此,我在触摸设备上停用了悬停功能,因为在那里没有意义。(使用检测) - johjoh

4
#btn{
width:100px; height:100px;/*the dimensions of your image*/
background:url(bird.png) left top no-repeat;
}
#btn:hover{
background-position:left bottom;/* pixel references can be used if prefered */
}

使用这样的图片:

alt text

注意:避免使用JS替换图片,因为如果图片没有被缓存,将会导致短暂的图片加载时间。

希望这能帮到你!

W.


CSS中的图像也没有被预缓存,特别是在IE浏览器中。 - Ruan Mendes
1
当您使用精灵时,浏览器会加载整个精灵图像(假设需要它的元素是可见的)。在这里,它是可见的,因此mouseover部分被加载,表面上导致预加载。 - Steven
为了最佳实践,#btn 应该是什么类型的元素?一个空白 div 吗? - AP257

3

使用CSS背景和“hover”

使用CSS精灵,即将两个图像合并为一个,然后使用CSS的:hover来切换图像。

使用CSS的一个优点是即使JavaScript关闭也可以工作。

使用单个图像的一个优点是避免了额外的HTTP请求。

参见:http://css-tricks.com/css-sprites/

帮助生成图像和CSS的工具:


0
你应该使用 :hover CSS 规则。

0
CSS是最好的选择。尽管你可能需要使用JavaScript预加载图像。

0

0

使用CSS精灵和:hover伪类。以下是原因:

  1. 通过JS或CSS切换图像源会在第一次鼠标悬停时导致“闪烁”,因为新图像被浏览器下载。如果使用精灵,就只有一个图像改变位置,所以不会出现闪烁。

  2. 单个图像减少了HTTP请求,使网站整体加载更快。

  3. 如果用户禁用JavaScript,它仍然可以工作。

  4. 所有浏览器类型都支持它(至少桌面浏览器支持,没有:hover状态的手机浏览器不计算在内)。

更多信息:http://css-tricks.com/css-sprites/


-1
$('#div1').hover(function(){
  this.style.color='white';
},function(){
 this.style.color='black;
});

或者

$('#div1').onmouseover()...
$('#div1').onmouseout()...

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