Cambiar la fuente de la imagen en rollover usando jQuery


443

Tengo algunas imágenes y sus imágenes de rollover. Utilizando jQuery, quiero mostrar / ocultar la imagen de rollover cuando ocurre el evento onmousemove / onmouseout. Todos los nombres de mis imágenes siguen el mismo patrón, así:

Imagen original: Image.gif

Imagen de rollover: Imageover.gif

Quiero insertar y eliminar la parte "sobre" de la fuente de la imagen en el evento onmouseover y onmouseout, respectivamente.

¿Cómo puedo hacerlo usando jQuery?


Escribí un pequeño tutorial con ejemplos para principiantes, Cambiar imagen con JavaScript (o jQuery) . También hay un ejemplo sin usar jQuery.
gothy

Cambiar imagen en mouseover dotnetspeaks.com/DisplayArticle.aspx?ID=89
Sumit

10
Justo lo que estoy buscando. ¡Gracias por publicar la pregunta!
Samuel Meddows

Tengo un problema como este ( Mi pregunta ). La respuesta a esta pregunta es excelente, pero en IE9 cada vez que pasa el botón, hay una solicitud adicional de imagen y es muy mala. ¿Algún cuerpo tiene mejor respuesta?
Iman

Respuestas:


620

Para configurar en listo:

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

Para aquellos que usan fuentes de imágenes 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);

            });
    });

77
Esto no funciona si el src es una url absoluta con a. en él (como www.example.com)
Kieran Andrews

8
Esto tampoco funciona si usa un dominio como www.over.com o si tiene overotro lugar en el URI.
Benjamin Manns

32
¿Puedo sugerir editar el .replace final con .replace ("over.gif", ".gif");
Nathan Koop el

2
Gracias por publicar esto. Espero que no te importe que ponga esto en mi blog. Mi blog es como un "cuaderno" y es mi "ir a la cosa" cuando olvido algo.
wenbert

1
No es necesario utilizar el método ".match (/[^\.font>+/)" y con Regex. El ".replace (". Gif "," over.gif ") es suficiente para que funcione.
Navigatron

114

Sé que estás preguntando sobre el uso de jQuery, pero puedes lograr el mismo efecto en los navegadores que tienen JavaScript desactivado usando 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);
}

Hay una descripción más larga aquí.

Aún mejor, sin embargo, es usar sprites: simple-css-image-rollover


1
Sí, pero es un poco más difícil hacer esto en los elementos de IMAGEN :) Además de eso, CSS significa la separación del contenido de la presentación. Si haces esto, te unes a esas cosas;) No puedes tener esto para un sitio grande, ¿verdad?
Ionuț Staicu

Estoy de acuerdo con usted sobre el CSS, pero parece que el autor de la pregunta quería una solución genérica que se aplique a varias imágenes a la vez.
Jarrod Dixon

99
Esta solución es la opción más preferible, a menos que esté haciendo algunos efectos. Estaba pensando exactamente lo mismo +1
Angel.King.47

66
Es la mejor solución. Para evitar esperar la nueva imagen (solicitud de red), use una sola imagen.jpg y juegue con la posición de fondo para mostrar / ocultar la buena.
kheraud

2
@kheraud Mover una sola imagen es una buena solución, pero si es la mejor o no depende del tamaño de la imagen. Por ejemplo, en Internet lento, la descarga de dos imágenes de 1920 px de ancho en un archivo gigantesco llevaría inaceptablemente largo. Para iconos e imágenes pequeñas, aunque funciona bien.
DACrosby

63

Si tiene más de una imagen y necesita algo genérico que no dependa de una convención de nomenclatura.

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
Este fue el indicado para mí. Solo recuerde poner el javascript dentro de una función para ejecutarlo, es decir, cuando el DOM esté listo "$ (function () {});"
Mischa

En realidad, se dispara cuando la página aún se está cargando, y cuando el cursor del mouse está realmente sobre el selector, reemplaza la url para que el efecto se invierta
Mike

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

44
Tenga en cuenta que ir de esta manera significará que el usuario verá una pausa en el primer desplazamiento mientras el navegador recupera la imagen.
Tyson

1
@Tyson Odia subirse al tren tarde, pero puede precargar las imágenes a través de Javascript o CSS
cbr

Tampoco funciona en Chrome 37. $ (this) .attr ("src", src) funciona bien.
Le Droid

25

Una solución genérica que no lo limita a "esta imagen" y "esa imagen" solo puede ser agregar las etiquetas 'onmouseover' y 'onmouseout' al código HTML mismo.

HTML

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

JavaScript

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

Dependiendo de su configuración, tal vez algo como esto funcionaría mejor (y requiere menos modificación de 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
    });
});

Es posible que desee cambiar la clase de imágenes de la primera línea. Si necesita más clases de imágenes (o una ruta diferente), puede usar

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

y así.

Debería funcionar, no lo probé :)


2
+1 Doh, ¡se olvidó del asistente de evento flotante! Y una buena sugerencia sobre agregar una clase a las imágenes - realmente es una mejor práctica :)
Jarrod Dixon

1
Esa es una solución mucho mejor porque almacena en caché la antigua fuente de imagen.
trante

La parte negativa es que, si la imagen está en la parte inferior de la página y hay 10-20 imágenes, el diseño se vuelve extraño.
trante

13

Esperaba un über one liner como:

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

6

Si la solución que busca es un botón animado, lo mejor que puede hacer para mejorar el rendimiento es la combinación de sprites y CSS. Un sprite es una imagen enorme que contiene todas las imágenes de su sitio (encabezado, logotipo, botones y todas las decoraciones que tiene). Cada imagen que tiene utiliza una solicitud HTTP, y cuantas más solicitudes HTTP, más tiempo llevará cargar.

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

Las 0px 0pxcoordenadas serán la esquina superior izquierda de tus sprites.

Pero si está desarrollando algún álbum de fotos con Ajax o algo así, entonces JavaScript (o cualquier marco) es el mejor.

¡Que te diviertas!


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

Mientras buscaba una solución hace algún tiempo, encontré un script similar al siguiente, que después de algunos ajustes, comencé a trabajar para mí.

Maneja dos imágenes, que casi siempre están predeterminadas en "apagado", donde el mouse está fuera de la imagen (image-example_off.jpg), y el ocasional "on", donde para las veces que el mouse está suspendido, la imagen alternativa requerida ( image-example_on.jpg) se muestra.

<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>

Me doy cuenta de que la función anterior se ejecutará para todas las imágenes dentro del DOM, ya que actualmente está codificada. Proporcionar un contexto adicional lo haría enfocar el efecto a elementos img específicos.
Kristopher Rout

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>

2

He hecho algo como el siguiente código :)

Solo funciona cuando tienes un segundo archivo llamado _hover, por ejemplo, facebook.pngyfacebook_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);
});

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

1

Adaptado del código de Richard Ayotte: para apuntar a un img en una lista ul / li (que se encuentra a través de la clase div wrapper aquí), algo como esto:

$('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') }
); 
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.