Zmień źródło obrazu podczas najazdu za pomocą jQuery


443

Mam kilka zdjęć i ich obrazy najazdu. Za pomocą jQuery chcę pokazać / ukryć obraz najazdu, gdy nastąpi zdarzenie onmousemove / onmouseout. Wszystkie moje nazwy obrazów mają ten sam wzór, taki jak ten:

Oryginalny obraz: Image.gif

Obraz najazdu: Imageover.gif

Chcę wstawić i usunąć część „over” źródła obrazu odpowiednio w zdarzeniu onmouseover i onmouseout.

Jak mogę to zrobić za pomocą jQuery?


Napisałem małą instrukcję z przykładami dla początkujących, Zmień obraz za pomocą JavaScript (lub jQuery) . Jest też przykład bez użycia jQuery.
gothy,

Zmień obraz na wskaźniku
Sumit

10
Właśnie tego szukam. Dziękujemy za opublikowanie pytania!
Samuel Meddows

Mam taki problem ( moje pytanie ). Odpowiedź na to pytanie jest świetna, ale w IE9 za każdym razem, gdy przesuwasz przycisk, pojawia się dodatkowe żądanie obrazu i jest bardzo złe. Czy jakieś ciało ma lepszą odpowiedź?
Iman

Odpowiedzi:


620

Aby skonfigurować gotowe:

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

Dla tych, którzy korzystają ze źródeł obrazu 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
To nie działa, jeśli src jest absolutnym adresem URL z. w nim (np. www.example.com)
Kieran Andrews

8
To również nie działa, jeśli korzystasz z domeny takiej jak www.over.com lub masz overgdzieś inny identyfikator URI.
Benjamin Manns,

32
czy mogę zasugerować edycję końcowego .replace za pomocą .replace („over.gif”, „.gif”);
Nathan Koop,

2
Dzięki za opublikowanie tego. Mam nadzieję, że nie masz nic przeciwko, że umieściłem to na moim blogu. Mój blog jest jak „zeszyt” i jest to moje „pójście do rzeczy”, gdy coś zapomnę.
wenbert

1
Nie jest konieczne stosowanie metody „.match (/[^\.]+/)” i Regex. „.Replace („. Gif ”,„ over.gif ”) wystarczy, by działało.
Navigatron

114

Wiem, że pytasz o użycie jQuery, ale możesz uzyskać ten sam efekt w przeglądarkach, w których JavaScript jest wyłączony za pomocą 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);
}

Jest dłuższy opis tutaj

Jednak jeszcze lepiej jest użyć sprajtów: proste-css-image-rollover


1
tak, ale trudniej to zrobić na elementach OBRAZ :) Poza tym CSS oznacza oddzielenie treści od prezentacji. Jeśli to zrobisz, dołączysz do tych rzeczy;) Nie możesz mieć tego na dużej stronie, prawda?
Ionuț Staicu

Zgadzam się z tobą w sprawie css, ale wydaje się, że autor pytania chciał ogólnego rozwiązania, które dotyczyłoby wielu obrazów jednocześnie.
Jarrod Dixon

9
To rozwiązanie jest najbardziej preferowaną opcją, chyba że robisz jakieś efekty. Myślałem dokładnie o tym samym +1
Angel.King.47

6
To najlepsze rozwiązanie. Aby uniknąć oczekiwania na nowy obraz (żądanie sieciowe), użyj pojedynczego obrazu.jpg i graj z pozycją tła, aby pokazać / ukryć dobry.
kheraud

2
@kheraud Przenoszenie pojedynczego obrazu jest dobrym rozwiązaniem, ale to, czy jest najlepsze, czy nie, zależy od rozmiaru obrazu. Na przykład w przypadku wolnego Internetu pobranie dwóch zdjęć o szerokości 1920px w jednym gigantycznym pliku zajęłoby zbyt wiele czasu. W przypadku ikon i małych obrazów to działa dobrze.
DACrosby

63

Jeśli masz więcej niż jeden obraz i potrzebujesz czegoś ogólnego, który nie zależy od konwencji nazewnictwa.

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
To był ten dla mnie. Pamiętaj tylko, aby umieścić javascript wewnątrz funkcji, aby go wykonać, tj. Gdy DOM jest gotowy „$ (function () {});”
Mischa

W rzeczywistości uruchamia się, gdy strona wciąż się ładuje, a gdy kursor myszy znajduje się nad selektorem, zastępuje adres URL, więc efekt jest odwrócony
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
Należy pamiętać, że przejście w ten sposób oznacza, że ​​użytkownik zobaczy pauzę po pierwszym najechaniu kursorem, gdy przeglądarka pobierze obraz.
Tyson

1
@Tyson Hate, aby wskoczyć do pociągu późno, ale można wstępnie załadować obrazy za pomocą Javascript lub CSS
cbr

Nie działa również w Chrome 37. $ (this) .attr ("src", src) działa dobrze.
Le Droid

25

Ogólnym rozwiązaniem, które nie ogranicza cię tylko do „tego obrazu” i „tego obrazu”, może być dodanie znaczników „onmouseover” i „onmouseout” do samego kodu HTML.

HTML

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

JavaScript

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

W zależności od konfiguracji może coś takiego działałoby lepiej (i wymaga mniej modyfikacji 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
    });
});

Możesz zmienić klasę obrazów z pierwszej linii. Jeśli potrzebujesz więcej klas obrazów (lub innej ścieżki), możesz użyć

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

i tak dalej.

Powinno działać, nie testowałem tego :)


2
+1 Doh, zapomniałem o pomocniku zdarzenia na zawisie! I fajna sugestia dotycząca dodania klasy do zdjęć - to naprawdę najlepsza praktyka :)
Jarrod Dixon

1
To o wiele lepsze rozwiązanie, ponieważ buforuje stare źródło obrazu.
trante

Negatywną częścią jest to, że jeśli obraz znajduje się na dole strony i jest 10-20 obrazów, układ staje się dziwny.
trante

13

Miałem nadzieję na wkładkę über one jak:

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

6

Jeśli szukasz rozwiązania z animowanym przyciskiem, najlepszym sposobem na poprawę wydajności jest połączenie duszków i CSS. Duszek to ogromny obraz, który zawiera wszystkie obrazy z Twojej witryny (nagłówek, logo, przyciski i wszystkie dekoracje). Każdy posiadany obraz korzysta z żądania HTTP, a im więcej żądań HTTP, tym więcej czasu zajmie jego załadowanie.

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

Te 0px 0pxwspółrzędne będą lewym górnym rogu ze swoimi duchy.

Ale jeśli tworzysz jakiś album ze zdjęciami z Ajaxem lub coś w tym stylu, JavaScript (lub dowolny framework) jest najlepszy.

Baw się dobrze!


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

Szukając rozwiązania jakiś czas temu, znalazłem skrypt podobny do poniższego, który po drobnych poprawkach zacząłem pracować dla siebie.

Obsługuje dwa obrazy, które prawie zawsze domyślnie są wyłączone, gdy mysz jest wyłączona z obrazu (image-example_off.jpg), a sporadycznie „włączone”, gdzie dla czasu najechania myszą wymagany obraz alternatywny ( image-example_on.jpg) jest wyświetlany.

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

Zdaję sobie sprawę, że powyższa funkcja byłaby wykonywana dla wszystkich obrazów w DOM, ponieważ jest obecnie zakodowana. Dostarczenie dalszego kontekstu sprawiłoby, że skupiłoby to efekt na określonych elementach img.
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

Zrobiłem coś takiego jak poniższy kod :)

Działa tylko wtedy, gdy masz na przykład drugi plik o nazwie _hover facebook.pngifacebook_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

Zaadaptowano z kodu Richarda Ayotte - Aby celować w img na liście ul / li (znalezionej tutaj przez klasę otoki div), coś takiego:

$('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') }
); 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.