iT邦幫忙

1

jquery換多張圖

小妹最近在學習製作網頁中使用jQuery

今日遇到的問題是在一個div中會有很多張圖片

    <div class="card_area">
            <div class="card card1">
                <img src="/images/index/card/gray_1.jpg" alt="">
            </div>
            <div class="card card2">
                <img src="/images/index/card/gray_2.jpg" alt="">
            </div>
            <div class="card card3">
                <img src="/images/index/card/gray_3.jpg" alt="">
            </div>
            <div class="card card4">
                <img src="/images/index/card/gray_4.jpg" alt="">
            </div>
            <div class="card card5">
                <img src="/images/index/card/gray_5.jpg" alt="">
            </div>
            <div class="card card6">
                <img src="/images/index/card/gray_6.jpg" alt="">
            </div>
            <div class="card card7">
                <img src="/images/index/card/gray_7.jpg" alt="">
            </div>
            <div class="card card8">
                <img src="/images/index/card/gray_8.jpg" alt="">
            </div>
            <div class="card card9">
                <img src="/images/index/card/gray_9.jpg" alt="">
            </div>
            <div class="card card10">
                <img src="/images/index/card/gray_10.jpg" alt="">
            </div>
            <div class="card card11">
                <img src="/images/index/card/gray_11.jpg" alt="">
            </div>
            <div class="card card12">
                <img src="/images/index/card/gray_12.jpg" alt="">
            </div>
            <div class="card card13">
                <img src="/images/index/card/gray_13.jpg" alt="">
            </div>
            <div class="card card14">
                <img src="/images/index/card/gray_14.jpg" alt="">
            </div>
            <div class="card card15">
                <img src="/images/index/card/gray_15.jpg" alt="">
            </div>
            <div class="card card16">
                <img src="/images/index/card/gray_16.jpg" alt="">
            </div>
            <div class="card card17">
                <img src="/images/index/card/gray_17.jpg" alt="">
            </div>
            <div class="card card18">
                <img src="/images/index/card/gray_18.jpg" alt="">
            </div>
            <div class="card card19">
                <img src="/images/index/card/gray_19.jpg" alt="">
            </div>
            <div class="card card20">
                <img src="/images/index/card/gray_20.jpg" alt="">
            </div>
            <div class="card card21">
                <img src="/images/index/card/gray_21.jpg" alt="">
            </div>
            <div class="card card22">
                <img src="/images/index/card/gray_22.jpg" alt="">
            </div>
            <div class="card card23">
                <img src="/images/index/card/gray_23.jpg" alt="">
            </div>
            <div class="card card24">
                <img src="/images/index/card/gray_24.jpg" alt="">
            </div>
            <div class="card card25">
                <img src="/images/index/card/gray_25.jpg" alt="">
            </div>
            <div class="card card26">
                <img src="/images/index/card/gray_26.jpg" alt="">
            </div>
            <div class="card card27">
                <img src="/images/index/card/gray_27.jpg" alt="">
            </div>
            <div class="card card28">
                <img src="/images/index/card/gray_28.jpg" alt="">
            </div>
            <div class="card card29">
                <img src="/images/index/card/gray_29.jpg" alt="">
            </div>
            <div class="card card30">
                <img src="/images/index/card/gray_30.jpg" alt="">
            </div>
        </div>

我想要hover過去後圖片的src會改變成另外一張圖

然而我目前只會以最笨方法寫下改變src,

    $(".card1").mouseover(function () {
        $(".card1 img").attr("src", "/images/index/card/colorful_1.png");
    });
    $(".card1").mouseout(function () {
        $(".card1 img").attr("src", "/images/index/card/gray_1.jpg");
    });

    $(".card2").mouseover(function () {
        $(".card2 img").attr("src", "/images/index/card/colorful_2.png");
    });
    $(".card2").mouseout(function () {
        $(".card2 img").attr("src", "/images/index/card/gray_2.jpg");
    });
    
    ....

但我知道這不是好方法
要是有100張我就完蛋了...
所以嘗試想要用for迴圈

    var card_name = document.querySelectorAll(".card");
    var card_arr = Array.from(card_name);
    console.log(card_arr);

  for (var i = 0; i < card_arr.length; i++) {
      
        $(".card").mouseover(function () {
            $(".card" + [i] + " img").attr("src", "/images/index/card/colorful_" + [i] + ".png");
        });
        $(".card").mouseout(function () {
            $(".card" + [i] + " img").attr("src", "/images/index/card/gray_" + [i] + ".jpg");
        });

    }

結果很詭異的是不管hover到哪張
都是最後一張圖片會改變src

console.log沒有看到出錯

請問該怎麼修正我的程式呢?

新手謝過各位

dragonH iT邦大師 7 級 ‧ 2019-06-21 19:21:10 檢舉
我回復次數滿了

所以貼這裡給你參考

https://codepen.io/dragonH/pen/LKWNNr?editors=1011

沒有必要把 event listener 放到迴圈裡

然後你可以考慮把圖直接放到background裡
okaybeok iT邦新手 5 級 ‧ 2019-06-24 10:06:38 檢舉
非常謝謝您給我參考!!
看來我還有多基礎需要搞懂
不過請問為何建議是放背景圖片呢?
謝謝您
dragonH iT邦大師 7 級 ‧ 2019-06-25 11:07:18 檢舉
@okaybeok

因為你看的需求看起來就是一個div 裡只放一個 圖片

與其多用一個<img>來放圖片

還不如直接把圖片設成<div> 的背景

也可以避免掉一些mouse event 可能會有的 bug

1 個回答

5
ccutmis
iT邦研究生 2 級 ‧ 2019-06-21 23:01:55
最佳解答

範例:

<!doctype html>
<html><head>
<meta charset="utf-8">
<title>jQuery在mouseover跟mouseout時換圖demo</title>
<script
 src="https://code.jquery.com/jquery-3.4.0.min.js"
 integrity="sha256-BJeo0qm959uMBGb65z40ejJYGSgR7REI4+CW1fNKwOg="
 crossorigin="anonymous"></script>
<script>
$(function(){
	$('.card img').mouseover(function () {
		this.src=this.src.replace(/(.*?)(\/)(\w{4,8})(_\d{1,2})(.jpg)$/, "$1$2colorful$4$5");
	}).mouseout(function () {
		this.src=this.src.replace(/(.*?)(\/)(\w{4,8})(_\d{1,2})(.jpg)$/, "$1$2gray$4$5");
	});
});
</script>
</head>
<body>
   <div class="card_area">
            <div class="card card1">
                <img src="/images/index/card/gray_1.jpg" alt="">
            </div>
            <div class="card card2">
                <img src="/images/index/card/gray_2.jpg" alt="">
            </div>
   </div>
</body>
</html>

說明:
既然用了jquery就要多利用它好用的選擇器(selector),
例如html長這樣:

<div class="card_area">
	<div class="card card1">
		<img src="/images/index/card/gray_1.jpg" alt="">
	</div>
	<div class="card card2">
		<img src="/images/index/card/gray_2.jpg" alt="">
	</div>
	<!--....略....-->
	<div class="card card30">
		<img src="/images/index/card/gray_30.jpg" alt="">
	</div>
</div>

用 $('.card img') 就能指到所有的圖片,
接著用jquery的mouseover跟mouseout事件配合RegExp
處理滑鼠移入時把src字串裡的'gray'換成'colorful'
處理滑鼠移出時把src字串裡的'colorful'換成'gray'
底下就是樓主問的jquery源碼部份:

$(function(){
	$('.card img').mouseover(function () {
		this.src=this.src.replace(/(.*?)(\/)(\w{4,8})(_\d{1,2})(.jpg)$/, "$1$2colorful$4$5");
	}).mouseout(function () {
		this.src=this.src.replace(/(.*?)(\/)(\w{4,8})(_\d{1,2})(.jpg)$/, "$1$2gray$4$5");
	});
});

上列源碼作用之後,不管你有幾個

<div class="card cardxx"><img src='...'></div>

都會有同樣的換圖效果。

看更多先前的回應...收起先前的回應...
okaybeok iT邦新手 5 級 ‧ 2019-06-24 10:17:19 檢舉

謝謝您的回覆~~~
想請問一下我上網查了您提到的RegExp,是正規表示式
但我不太能理解這個正規表示式該怎麼產生出您寫出這樣格式/images/emoticon/emoticon06.gif

想請問/(.?)(/)(\w{4,8})(\d{1,2})(.jpg)$/, "$1$2colorful$4$5這是怎麼產生的呢?

謝謝您

ccutmis iT邦研究生 2 級 ‧ 2019-06-24 11:34:25 檢舉

有個經典的IT笑話:
如果你打算用正規表示式來處理問題,那麼恭喜你~現在你有兩個問題了...

正規表示式很難用幾句話講完全部內容,所以我會建議你去找一些網路上不錯的教學文來看,
例如邦友寫的文章:
https://ithelp.ithome.com.tw/articles/10212173
https://ithelp.ithome.com.tw/articles/10212174

或者找O'REILLY書商出的Regular Expression 主題的書來看

然後就是練習再練習而已,有點像是學英文,你需要環境跟多講,
有些例子是可以舉一反三的(例如我這邊demo給你看的),
有些則是學了可以重覆套用(最常見的就是輸入email或電話格式驗證這類)


想請問/(.?)(/)(\w{4,8})(\d{1,2})(.jpg)$/, "$1$2colorful$4$5這是怎麼產生的呢?

原本的html字串是

/images/index/card/gray_1.jpg

正規表示式的部份是

/(.*?)(\/)(\w{4,8})(_\d{1,2})(.jpg)$/

這裡可以把正規式當作是字串匹配樣版,
裡面的()是用來作群組的,之後會用到的$1$2$3...$5就是對應到()

(.jpg)$

這個意思就是字串最後面是.jpg

(_\d{1,2})

這個的意思就是匹配"_"後面接數字(0-9)最少出現1次最多2次(符合1,2,3...10,11,12...97,98,99)

(\w{4,8})

這個是匹配英文數字或底線最少出現4次最多8次(符合gray,colorful; 不符合abc,abcdefghi)

(\/)

這個是匹配"/"因為會跟正規表示式的/.../ 衝到 所以要加上倒斜線 這樣它就知道你要匹配的是/

(.*?)

這個用來匹配不特定長度的字串

把它們組合起來就是

"不特定長度的字串" 加上 "/" 加上 "英文數字或底線最少出現4次最多8次" 加上 "_後面接數字(0-9)最少出現1次最多2次" 加上 "字串最後面是.jpg"

以上就是

/(.*?)(\/)(\w{4,8})(_\d{1,2})(.jpg)$/

整段的意思,
當然寫法不只這一種,也有其它可以作到同樣意思的寫法,等你學習到一定水平就知道了,這邊略過不表。

重新來看這段:

/(.*?)(\/)(\w{4,8})(_\d{1,2})(.jpg)$/, "$1$2colorful$4$5"

這個是javascript的str.replace函式,前半段是用正則作搜尋,後半段是用搜尋出來的結果作置換
前面有提到()是群組,前半段有五個()分別對應到$1 $2 $3 $4 $5
$3就是被搜尋字串的gray,所以我們在置換的部份只留下$1$2$4$5 並在$2跟$4中間插入colorful

整段的意思就是如果字串結尾是 gray_nn.jpg 就置換成 colorful_nn.jpg 其餘內容不變

我的正則是土炮學法,學校沒教過,都是從書本或網路上學的,你現在的問題我也遇過,不用擔心,遇到不熟的或弄不出來的就去查去問,有些現在不懂也沒關係,先照抄把功能做出來,有空閒再思考這怎麼做的,多練習就會熟了...


正則表示式是一把瑞士刀,在很多場合都用的到,像是一些常用文字編輯器如atom,notepad++等等都可以在搜尋取代時使用正則,編寫系統維護腳本,或是用python寫一些網路爬虫...等等,推薦花點時間學習,等你熟悉的時候你會知道花這些時間是值得的。

okaybeok iT邦新手 5 級 ‧ 2019-06-26 13:52:12 檢舉

嗚嗚
超級感謝您願意花這麼多心思回答我的問題
因為基礎還很差
javascript 和 jQuery都有很多要學
若是之後基礎都好了
我有時間會往這方面學習的~

謝謝~/images/emoticon/emoticon02.gif

ccutmis iT邦研究生 2 級 ‧ 2019-06-28 12:18:45 檢舉

恩 加油... /images/emoticon/emoticon82.gif

我要發表回答

立即登入回答