Modifier la source d'image lors du survol à l'aide de jQuery

443

J'ai quelques images et leurs images de survol. En utilisant jQuery, je veux afficher / masquer l'image de survol lorsque l'événement onmousemove / onmouseout se produit. Tous mes noms d'images suivent le même modèle, comme ceci:

Image originale: Image.gif

Image de survol: Imageover.gif

Je veux insérer et supprimer la partie "over" de la source d'image dans l'événement onmouseover et onmouseout, respectivement.

Comment puis-je le faire en utilisant jQuery?

Sachin Gaur
la source
J'ai écrit un petit tutoriel avec des exemples pour les débutants, Changer l'image avec JavaScript (ou jQuery) . Il y a aussi un exemple sans utiliser jQuery.
gothy
10
Exactement ce que je recherche. Merci d'avoir posté la question!
Samuel Meddows
J'ai un problème comme celui-ci ( ma question ). La réponse à cette question est excellente mais dans IE9 à chaque fois que vous passez le bouton, il y a une demande d'image supplémentaire et c'est très mauvais. Est-ce que n'importe quel corps a une meilleure réponse?
Iman

Réponses:

620

Pour configurer sur prêt:

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

Pour ceux qui utilisent des sources d'images 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);

            });
    });
Jarrod Dixon
la source
7
Cela ne fonctionne pas si le src est une URL absolue avec un. dedans (comme www.example.com)
Kieran Andrews
8
Cela ne fonctionne pas non plus si vous utilisez un domaine comme www.over.com, ou si vous avez overun autre emplacement dans l'URI.
Benjamin Manns
32
puis-je suggérer de modifier le .replace final avec .replace ("over.gif", ".gif");
Nathan Koop
2
Merci d'avoir posté ça. J'espère que cela ne vous dérange pas que je mette cela sur mon blog. Mon blog est comme un "cahier" et c'est mon "go-to-thing" quand j'oublie quelque chose.
wenbert
1
Il n'est pas nécessaire d'utiliser la méthode ".match (/[^\.[+/)" et avec Regex. Le ".replace (". Gif "," over.gif ") suffit pour que cela fonctionne.
Navigatron
114

Je sais que vous posez des questions sur l'utilisation de jQuery, mais vous pouvez obtenir le même effet dans les navigateurs qui ont désactivé JavaScript en utilisant 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);
}

Il y a une description plus longue ici

Encore mieux, cependant, est d'utiliser des sprites: simple-css-image-rollover

Tyson
la source
1
oui, mais c'est un peu plus difficile à faire sur les éléments IMAGE :) En plus de cela, CSS signifie la séparation du contenu de la présentation. Si vous faites cela, vous vous joignez à ces choses;) Vous ne pouvez pas avoir cela pour un grand site, non?
Ionuț Staicu
Je suis d'accord avec vous sur le CSS, mais il semble que l'auteur de la question voulait une solution générique qui s'applique à plusieurs images à la fois.
Jarrod Dixon
9
Cette solution est l'option la plus préférable, sauf si vous faites des effets. Je pensais exactement la même chose +1
Angel.King.47
6
C'est la meilleure solution. Pour éviter d'attendre la nouvelle image (requête réseau), utilisez un seul fichier image.jpg et jouez avec background-position pour afficher / masquer la bonne.
kheraud
2
@kheraud Déplacer une seule image est une bonne solution, mais qu'elle soit la meilleure ou non dépend de la taille de l'image. Par exemple, sur Internet lent, le téléchargement de deux images de 1 920 pixels de large dans un fichier gigantesque prendrait un temps inacceptable. Pour les icônes et les petites images, cela fonctionne bien.
DACrosby
63

Si vous avez plusieurs images et que vous avez besoin de quelque chose de générique qui ne dépend pas d'une convention de dénomination.

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') 
    })
});
Richard Ayotte
la source
1
C'était celui pour moi. N'oubliez pas de mettre le javascript dans une fonction pour l'exécuter, c'est-à-dire lorsque le DOM est prêt "$ (function () {});"
Mischa
En fait, il se déclenche lorsque la page est encore en cours de chargement, et lorsque le curseur de votre souris se trouve sur le sélecteur, il remplace l'URL, l'effet est donc inversé
Mike
57
    /* Teaser image swap function */
    $('img.swap').hover(function () {
        this.src = '/images/signup_big_hover.png';
    }, function () {
        this.src = '/images/signup_big.png';
    });
jonasl
la source
4
Gardez à l'esprit que cette méthode signifie que l'utilisateur verra une pause au premier survol pendant que le navigateur récupère l'image.
Tyson
1
@Tyson Hate pour monter tard dans le train, mais vous pouvez précharger les images via Javascript ou CSS
cbr
Ne fonctionne pas non plus sur Chrome 37. $ (this) .attr ("src", src) fonctionne très bien.
Le Droid
25

Une solution générique qui ne vous limite pas à "cette image" et "cette image" seulement peut être d'ajouter les balises "onmouseover" et "onmouseout" au code HTML lui-même.

HTML

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

Javascript

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

Selon votre configuration, peut-être que quelque chose comme ça fonctionnerait mieux (et nécessite moins de modifications 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"]);
  }
DACrosby
la source
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
    });
});

Vous souhaiterez peut-être modifier la classe d'images à partir de la première ligne. Si vous avez besoin de plus de classes d'images (ou d'un chemin différent), vous pouvez utiliser

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

etc.

Ça devrait marcher, je ne l'ai pas testé :)

Ionuț Staicu
la source
2
+1 Doh, j'ai oublié l'assistant d'événement en vol stationnaire! Et une bonne suggestion sur l'ajout d'une classe aux images - c'est vraiment une meilleure pratique :)
Jarrod Dixon
1
C'est une bien meilleure solution car elle met en cache l'ancienne source d'image.
trante
La partie négative est que si l'image est en bas de la page et qu'il y a 10 à 20 images, la mise en page devient bizarre.
trante
13

J'espérais un über one liner comme:

$("img.screenshot").attr("src", $(this).replace("foo", "bar"));
chovy
la source
6

Si la solution que vous recherchez est un bouton animé, le mieux que vous puissiez faire pour améliorer les performances est la combinaison de sprites et CSS. Un sprite est une image énorme qui contient toutes les images de votre site (en-tête, logo, boutons et toutes les décorations que vous avez). Chaque image que vous avez utilise une requête HTTP et plus il y a de requêtes HTTP, plus il faudra de temps pour le charger.

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

Les 0px 0pxcoordonnées seront le coin supérieur gauche de vos sprites.

Mais si vous développez un album photo avec Ajax ou quelque chose comme ça, alors JavaScript (ou n'importe quel framework) est le meilleur.

S'amuser!

mat
la source
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); 
});
iamrasec
la source
4

En cherchant une solution il y a quelque temps, j'ai trouvé un script similaire à celui ci-dessous, qui après quelques ajustements, j'ai commencé à travailler pour moi.

Il gère deux images, qui sont presque toujours par défaut "off", où la souris est hors de l'image (image-example_off.jpg), et le "on" occasionnel, où pour les fois où la souris est survolée, l'image alternative requise ( image-example_on.jpg) s'affiche.

<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>
Kristopher Rout
la source
Je me rends compte que la fonction ci-dessus s'exécuterait pour toutes les images dans le DOM tel qu'il est actuellement codé. Fournir un contexte supplémentaire lui permettrait de concentrer l'effet sur des éléments img spécifiques.
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>
Imran
la source
2

J'ai créé quelque chose comme le code suivant :)

Cela ne fonctionne que lorsque vous avez un deuxième fichier nommé avec _hover, par exemple, facebook.pngetfacebook_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);
});
Grzegorz
la source
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();
Gustav Westling
la source
1

Adapté du code de Richard Ayotte - Pour cibler un img dans une liste ul / li (trouvée via la classe div wrapper ici), quelque chose comme ceci:

$('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') }
); 
anoldermark
la source