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?

Sachin Gaur
źródło
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);

            });
    });
Jarrod Dixon
źródło
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

Tyson
źródło
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') 
    })
});
Richard Ayotte
źródło
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';
    });
jonasl
źródło
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"]);
  }
DACrosby
źródło
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 :)

Ionuț Staicu
źródło
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"));
chovy
źródło
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!

matowy
źródło
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
źródło
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>
Kristopher Rout
źródło
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>
Imran
źródło
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);
});
Grzegorz
źródło
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
źródło
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') }
); 
anoldermark
źródło