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.