画像にクラス名を追加するだけでアニメーションロールオーバーできるjQueryのスクリプト

JavaScriptを使ったロールオーバーって大体imgにクラス名を追加するだけで出来るタイプが多いですよね。同じ感じでアニメーションロールオーバーも出来たらいいよね!って思って作りました。きっと同じ様に思っている人もたくさんいるはずだし。。。まー、ソースも綺麗じゃないし、バグだってあるかもしませんが、きっと誰かが素敵に書き換えてくれるでしょう。既にあるかもですが・・・。

Demo

※プラグイン化したものを公開していますのでよろしければ画像にクラス名を追加するだけでアニメーションロールオーバーできるjQueryのプラグインをご覧下さい。

必要なファイル

対応ブラウザ

  • Google Chrome
  • Safari4~
  • Firefox3~
  • Internet Explorer6~
  • Opera11

※Windowsのみの確認です。

コーディング&設定

HTML

HTMLヘッダー内でjquery.jsを読み込む。

<script src="jquery.js" type="text/javascript"></script>

ロールオーバーさせるimgclassを設定します。

<img src="sample1.gif" class="rollover">
<img src="sample2.gif" class="rollover">
<img src="sample3.gif" class="rollover">

ファイル名

ロールオーバー用画像(形式はなんでもOK)を用意し、ロールオーバー前の画像ファイル名の最後に_ovを追加する。その画像をロールオーバー前の画像と同じフォルダに入れる。

(例)ロールオーバー前の画像がsample.gifならsample_ov.gifというファイル名にする。

JavaScript

アニメーションの種類により下記から選んで記述。

  1. フェード
  2. 上からスライド
  3. 左からスライド
  4. フェードしながら上からスライド
  5. オフ画像が上にスライドしながら、オン画像が上からスライド
  6. フェードしながら拡大縮小
  7. 下からスライド
  8. 右からスライド

※2012/2/15 「7.下からスライド」と「8.右からスライド」を追加しました。

1.フェード

Demo

$(function(){

	function imgOvAnimeFade(){

		var ovClass = "rollover", //ロールオーバーする要素のクラス名
		ovStr = "_ov", //ロールオーバー後の画像に追加する文字列
		ovImg = "ovImg",
		speed = 500; //アニメーションの速度

		//classがrolloverのimg要素に対しての処理
		$("img."+ovClass).each(function(){

			var self = $(this),
			url = self.attr("src").replace(/^(.+)(\.[a-z]+)$/,"$1"+ovStr+"$2");

			function ovElmLen(){ //ロールオーバー画像表示確認関数
				return self.prev("img."+ovImg).length;
			}

			//ホバーイベント
			self.hover(
			function(){
				if(!self.attr("src").match(ovStr+".")){
					if(!ovElmLen()){
						if(jQuery.support.checkOn && jQuery.support.htmlSerialize && !window.globalStorage){ //Operaバグ対策
							self.before("<span style='display:inline-block;' class='"+ovImg+"' ></span>");
						}
						self.css({position:"relative"}).before("<img style='position:absolute;' class='"+ovImg+"' src='"+url+"' alt='' />");
					}
					self.stop().animate({opacity:"0"},speed);
				}
			},
			function(){
				if(ovElmLen()){
					self.stop().animate({opacity:"1"},speed,function(){
						self.css({position:"static"})
						.prevAll("."+ovImg).remove();
					});
				}
			})
			.each(function(){ //プリロード設定
				$("<img>").attr("src",url);
			});

		});

	}

	ImgOvAnimeFade();

});

※2012/2/15 上記スクリプトの記述を変更しました。

2.上からスライド

Demo

$(function(){

	function imgOvAnimeSlideTop(){

		var ovClass = "rollover",
		ovStr = "_ov", //ロールオーバー後の画像に追加する文字列
		ovRrap = "ovRrap",
		ovImg = "ovImg",
		speed = 500; //アニメーションの速度

		$("img."+ovClass).each(function(){ //classがrolloverのimg要素に対しての処理

			var self = $(this),
			urlDef = self.attr("src"),
			urlChange = urlDef.replace(/^(.+)(\.[a-z]+)$/,"$1"+ovStr+"$2");

			function ovElm(){
				return self.prev("span."+ovImg);
			}
			function ovElmLen(){ //ロールオーバー画像表示確認関数
				return ovElm().length;
			}
			function w(){
				return self.width()+"px";
			}
			function h(){
				return self.height()+"px";
			}

			self.hover(
			function(){
				if(!self.attr("src").match(ovStr+".")){
					if(!ovElmLen()){
						if(jQuery.support.checkOn && jQuery.support.htmlSerialize && !window.globalStorage){ //Operaバグ対策
							self.before("<span style='display:inline-block;' class='"+ovImg+"' ></span>");
						}
						self.css({opacity:"0",position:"relative"})
						.before("<img style='position:absolute;' class='"+ovImg+"' src='"+urlDef+"' alt='' />")
						.before("<span style='width:"+w()+";height:0;background-image:url("+urlChange+");position:absolute;' class='"+ovImg+"'></span>");
					}
					ovElm().stop().animate({height:h()},speed);
				}
			},
			function(){
				if(ovElmLen()){
					ovElm().stop().animate({height:"0"},speed,function(){
						self.css({opacity:"1",position:"static"})
						.prevAll("."+ovImg).remove();
					});
				}
			})
			.each(function(){ //プリロード設定
				$("<img>").attr("src",urlChange);
			});

		});

	}

	ImgOvAnimeSlideTop();

});

※2012/2/15 上記スクリプトの記述を変更しました。

3.左からスライド

Demo

$(function(){

	function imgOvAnimeSlideLeft(){

		var ovClass = "rollover",
		ovStr = "_ov", //ロールオーバー後の画像に追加する文字列
		ovRrap = "ovRrap",
		ovImg = "ovImg",
		speed = 500; //アニメーションの速度

		$("img."+ovClass).each(function(){ //classがrolloverのimg要素に対しての処理

			var self = $(this),
			urlDef = self.attr("src"),
			urlChange = urlDef.replace(/^(.+)(\.[a-z]+)$/,"$1"+ovStr+"$2");

			function ovElm(){
				return self.prev("span."+ovImg);
			}
			function ovElmLen(){ //ロールオーバー画像表示確認関数
				return ovElm().length;
			}
			function w(){
				return self.width()+"px";
			}
			function h(){
				return self.height()+"px";
			}

			self.hover(
			function(){
				if(!self.attr("src").match(ovStr+".")){
					if(!ovElmLen()){
						if(jQuery.support.checkOn && jQuery.support.htmlSerialize && !window.globalStorage){ //Operaバグ対策
							self.before("<span style='display:inline-block;' class='"+ovImg+"' ></span>");
						}
						self.css({opacity:"0",position:"relative"})
						.before("<img style='position:absolute;' class='"+ovImg+"' src='"+urlDef+"' alt='' />")
						.before("<span style='display:inline;width:0;height:"+h()+";background-image:url("+urlChange+");position:absolute;' class='"+ovImg+"'></span>");
					}
					ovElm().stop().animate({width:w()},speed);
				}
			},
			function(){
				if(ovElmLen()){
					ovElm().stop().animate({width:"0"},speed,function(){
						self.css({opacity:"1",position:"static"})
						.prevAll("."+ovImg).remove();
					});
				}
			})
			.each(function(){ //プリロード設定
				$("<img>").attr("src",urlChange);
			});

		});

	}

	ImgOvAnimeSlideLeft();

});

※2012/2/15 上記スクリプトの記述を変更しました。

4.フェードしながら上からスライド

Demo

$(function(){

	function imgOvAnimeFadeSlideTop(){

		var ovClass = "rollover",
		ovStr = "_ov", //ロールオーバー後の画像に追加する文字列
		ovRrap = "ovRrap",
		ovImg = "ovImg",
		speed = 500; //アニメーションの速度

		$("img."+ovClass).each(function(){ //classがrolloverのimg要素に対しての処理

			var self = $(this),
			urlDef = self.attr("src"),
			urlChange = urlDef.replace(/^(.+)(\.[a-z]+)$/,"$1"+ovStr+"$2");

			function ovElm(){
				return self.prev("span."+ovImg);
			}
			function ovElmLen(){ //ロールオーバー画像表示確認関数
				return ovElm().length;
			}
			function w(){
				return self.width()+"px";
			}
			function h(){
				return self.height()+"px";
			}

			self.hover(
			function(){
				if(!self.attr("src").match(ovStr+".")){
					if(!ovElmLen()){
						if(jQuery.support.checkOn && jQuery.support.htmlSerialize && !window.globalStorage){ //Operaバグ対策
							self.before("<span style='display:inline-block;' class='"+ovImg+"' ></span>");
						}
						self.css({opacity:"0",position:"relative"})
						.before("<img style='position:absolute;' class='"+ovImg+"' src='"+urlDef+"' alt='' />")
						.before("<span style='display:inline;width:"+w()+";height:0;background-image:url("+urlChange+");position:absolute;' class='"+ovImg+"'></span>");
						ovElm().css({opacity:"0"});
					}
					ovElm().stop().animate({height:h(),opacity:"1"},speed);
				}
			},
			function(){
				if(ovElmLen()){
					ovElm().stop().animate({height:"0",opacity:"0"},speed,function(){
						self.css({opacity:"1",position:"static"})
						.prevAll("."+ovImg).remove();
					});
				}
			})
			.each(function(){ //プリロード設定
				$("<img>").attr("src",urlChange);
			});

		});

	}

	ImgOvAnimeFadeSlideTop();

});

※2012/2/15 上記スクリプトの記述を変更しました。

5.オフ画像が上にスライドしながら、オン画像が上からスライド

Demo

$(function(){

	function imgOvAnimeSlideTop2(){

		var ovClass = "rollover",
		ovStr = "_ov", //ロールオーバー後の画像に追加する文字列
		ovRrap = "ovRrap",
		ovImg = "ovImg",
		speed = 500; //アニメーションの速度

		$("img."+ovClass).each(function(){ //classがrolloverのimg要素に対しての処理

			var self = $(this),
			urlDef = self.attr("src"),
			urlChange = urlDef.replace(/^(.+)(\.[a-z]+)$/,"$1"+ovStr+"$2");

			function ovElm(){
				return self.prev("span."+ovImg);
			}
			function ovElmLen(){ //ロールオーバー画像表示確認関数
				return ovElm().length;
			}
			function w(){
				return self.width()+"px";
			}
			function h(){
				return self.height()+"px";
			}

			self.hover(
			function(){
				if(!self.attr("src").match(ovStr+".")){
					if(!ovElmLen()){
						if(jQuery.support.checkOn && jQuery.support.htmlSerialize && !window.globalStorage){ //Operaバグ対策
							self.before("<span style='display:inline-block;' class='"+ovImg+"' ></span>");
						}
						self.css({opacity:"0",position:"relative"})
						.before("<span style='display:inline;width:"+w()+";height:"+h()+";background-image:url("+urlDef+");position:absolute;' class='"+ovImg+"'></span>")
						.before("<span style='display:inline;width:"+w()+";height:0;background-image:url("+urlChange+");position:absolute;' class='"+ovImg+"'></span>");
					}
					ovElm().stop().animate({height:h()},speed)
					.prev("span."+ovImg).stop().animate({height:"0"},speed);
				}
			},
			function(){
				if(ovElmLen()){
					ovElm().stop().animate({height:"0"},speed)
					.prev("span."+ovImg).stop().animate({height:h()},speed,function(){
						self.css({opacity:"1",position:"static"})
						.prevAll("."+ovImg).remove();
					});
				}
			})
			.each(function(){ //プリロード設定
				$("<img>").attr("src",urlChange);
			});

		});

	}

	ImgOvAnimeSlideTop2();

});

※2012/2/15 上記スクリプトの記述を変更しました。

6.フェードしながら拡大縮小

Demo

$(function(){

	function imgOvAnimeFadeSizing(){

		var ovClass = "rollover",
		ovStr = "_ov", //ロールオーバー後の画像に追加する文字列
		ovRrap = "ovRrap",
		ovImg = "ovImg",
		speed = 500; //アニメーションの速度

		$("img."+ovClass).each(function(){ //classがrolloverのimg要素に対しての処理

			var self = $(this),
			urlDef = self.attr("src"),
			urlChange = urlDef.replace(/^(.+)(\.[a-z]+)$/,"$1"+ovStr+"$2");

			function ovElm(){
				return self.prev("span."+ovImg);
			}
			function ovElmLen(){ //ロールオーバー画像表示確認関数
				return ovElm().length;
			}
			function w(){
				return self.width()+"px";
			}
			function h(){
				return self.height()+"px";
			}

			self.hover(
			function(){
				if(!self.attr("src").match(ovStr+".")){
					if(!ovElmLen()){
						if(jQuery.support.checkOn && jQuery.support.htmlSerialize && !window.globalStorage){ //Operaバグ対策
							self.before("<span style='display:inline-block;' class='"+ovImg+"' ></span>");
						}
						self.css({opacity:"0",position:"relative"})
						.before("<span style='display:inline;width:"+w()+";height:"+h()+";background-image:url("+urlDef+");position:absolute;' class='"+ovImg+"'></span>")
						.before("<span style='display:inline;width:0;height:0;background-image:url("+urlChange+");position:absolute;' class='"+ovImg+"'></span>");
						ovElm().css({opacity:"0"});
					}
					ovElm().stop().animate({width:w(),height:h(),opacity:"1"},speed)
					.prev("span."+ovImg).stop().animate({width:"0",height:"0",opacity:"0"},speed);
				}
			},
			function(){
				if(ovElmLen()){
					ovElm().stop().animate({width:"0",height:"0",opacity:"0"},speed)
					.prev("span."+ovImg).stop().animate({width:w(),height:h(),opacity:"1"},speed,function(){
						self.css({opacity:"1",position:"static"})
						.prevAll("."+ovImg).remove();
					});
				}
			})
			.each(function(){ //プリロード設定
				$("<img>").attr("src",urlChange);
			});

		});

	}

	ImgOvAnimeFadeSizing();

});

※2012/2/15 上記スクリプトの記述を変更しました。

7.下からスライド

Demo

$(function(){

	function imgOvAnimeSlideBottom(){

		var ovClass = "rollover",
		ovStr = "_ov", //ロールオーバー後の画像に追加する文字列
		ovRrap = "ovRrap",
		ovImg = "ovImg",
		speed = 500; //アニメーションの速度

		$("img."+ovClass).each(function(){ //classがrolloverのimg要素に対しての処理

			var self = $(this),
			urlDef = self.attr("src"),
			urlChange = urlDef.replace(/^(.+)(\.[a-z]+)$/,"$1"+ovStr+"$2");

			function ovElm(){
				return self.prev("span."+ovImg);
			}
			function ovElmLen(){ //ロールオーバー画像表示確認関数
				return ovElm().length;
			}
			function w(){
				return self.width()+"px";
			}
			function h(){
				return self.height()+"px";
			}

			self.hover(
			function(){
				if(!self.attr("src").match(ovStr+".")){
					if(!ovElmLen()){
						if(jQuery.support.checkOn && jQuery.support.htmlSerialize && !window.globalStorage){ //Operaバグ対策
							self.before("<span style='display:inline-block;' class='"+ovImg+"' ></span>");
						}
						self.css({opacity:"0",position:"relative"})
						.before("<img style='position:absolute;' class='"+ovImg+"' src='"+urlChange+"' alt='' />")
						.before("<span style='width:"+w()+";height:"+h()+";background-image:url("+urlDef+");position:absolute;' class='"+ovImg+"'></span>");
					}
					ovElm().stop().animate({height:"0"},speed);
				}
			},
			function(){
				if(ovElmLen()){
					ovElm().stop().animate({height:h()},speed,function(){
						self.css({opacity:"1",position:"static"})
						.prevAll("."+ovImg).remove();
					});
				}
			})
			.each(function(){ //プリロード設定
				$("<img>").attr("src",urlChange);
			});

		});

	}

	ImgOvAnimeSlideBottom();

});

8.右からスライド

Demo

$(function(){

	function imgOvAnimeSlideRight(){

		var ovClass = "rollover",
		ovStr = "_ov", //ロールオーバー後の画像に追加する文字列
		ovRrap = "ovRrap",
		ovImg = "ovImg",
		speed = 500; //アニメーションの速度

		$("img."+ovClass).each(function(){ //classがrolloverのimg要素に対しての処理

			var self = $(this),
			urlDef = self.attr("src"),
			urlChange = urlDef.replace(/^(.+)(\.[a-z]+)$/,"$1"+ovStr+"$2");

			function ovElm(){
				return self.prev("span."+ovImg);
			}
			function ovElmLen(){ //ロールオーバー画像表示確認関数
				return ovElm().length;
			}
			function w(){
				return self.width()+"px";
			}
			function h(){
				return self.height()+"px";
			}

			self.hover(
			function(){
				if(!self.attr("src").match(ovStr+".")){
					if(!ovElmLen()){
						if(jQuery.support.checkOn && jQuery.support.htmlSerialize && !window.globalStorage){ //Operaバグ対策
							self.before("<span style='display:inline-block;' class='"+ovImg+"' ></span>");
						}
						self.css({opacity:"0",position:"relative"})
						.before("<img style='position:absolute;' class='"+ovImg+"' src='"+urlChange+"' alt='' />")
						.before("<span style='display:inline;width:"+w()+";height:"+h()+";background-image:url("+urlDef+");position:absolute;' class='"+ovImg+"'></span>");
					}
					ovElm().stop().animate({width:"0"},speed);
				}
			},
			function(){
				if(ovElmLen()){
					ovElm().stop().animate({width:w()},speed,function(){
						self.css({opacity:"1",position:"static"})
						.prevAll("."+ovImg).remove();
					});
				}
			})
			.each(function(){ //プリロード設定
				$("<img>").attr("src",urlChange);
			});

		});

	}

	ImgOvAnimeSlideRight();

});

解説

ホバー時に画像背景画像もつ要素を追加し下に重ねて、一番上の元画像opacityで透明にし要素を残しつつそれぞれをアニメーションさせます。元画像の要素が消えるとホバー状態ではなくってしまいますので。

あとがき

複数同時に使えるようにスクリプトを1つにまとめようかと思いましたが、出来るか分からないし、重くなりそうだし、めんどいし。ってことでやめました。まー、2種類同時使うことは稀だと思いますしね。

jquery.bgpos.jsを使いbackground-positionをアニメーションさせると違った動きもできます。今回の記事では使っていませんがね。気が向いたらそっちも記事にするかもです。

兎にも角にも、コレ作ってる間Operaちゃんのバグに悩まされた日々でしたとさ。

Comment

うみんちゅ

こんにちは!
早速活用させて頂きました!ありがとうございます。

なお、バグってほどではないですが、imgタグにcssでfloatを指定しているとオンマウス時の画像が正しい位置に表示されないようです。

念のためご報告までに。

ありがとうございました!

syuji

うみんちゅ さん、こんにちわ。
活用して頂きうれしいしだいです。

floatでオンマウス時の画像が正しい位置に表示されないとのこと、ご指摘ありがとう御座います。

今後イロイロ修正しようかと思っていますので、その際に直せたらと思います。

caramel

ネットでロールオーバーのアニメーションがないかな?と思ったときたどりつきました。
とても使いやすくて、利用させて頂きます。

ちょっとご質問なのですが、下からアニメーションさせたい場合の
パラメーター変更の仕方をよければ教えて頂けたらうれしいです。

Syuji

caramelさん。はじめまして。

下からアニメーションさせる場合についてですが、タイトルの通りクラス名追加だけで行うことを前提にお話します。

この場合は少しの変更で無理やり出来なことは無いのですが、動きがガタガタとしてしまうので別の方法で行いたいと思います。

「jquery.bgpos.js」を使用したいと思います。ただ、自分の見つけた最新バージョン(1.02)の「jquery.bgpos.js」だと「jQuery.js」の最新バージョン(1.7.1)を使用した場合Internet Explorerでエラーが出てしまいました。
ですので「jquery.bgpos.js」を少し改変しています。

以下がデモとJavaScriptです。(アニメーションの仕方が少し変わっています。)

DEMO
jquery.bgpos.js
画像にクラス名を追加するだけでロールオーバーを実現するjQueryのスクリプト

ついでにプラグイン化していますので、外部JavaScript内またはhead内に以下を記述して下さい。

jQuery(function($){
$(“ロールオーバーする要素につけるクラス名”).imgOvAnime({type: {on: “”, out: “”}});
});

大雑把に説明していますので、不明な点がありましたらまたご連絡ください。

あと、ココまで書いて気づいたことなのですが、「jquery.bgpos.js」を追加しなくてもできそうな方法が浮かんできました。
どうしても「jquery.bgpos.js」を追加したくない、アニメーションは変えたくないという場合は、ご連絡頂ければ試してみます。

caramel

あぁ、なんだかすぐすぐ対応して頂き、
しかも丁寧な対応をして頂いて申し訳ないです!!

早速使ってみたのですが、微妙に前回と動きが違うのですね。
あの、、前回の動きで下からは可能でしょうか?
なんだかいろいろ要望が多くてすいません、、T-T

沖縄でwebのお仕事すごいですね、自分は東京なのですが、
いずれは地方でwebの仕事できたらいいなぁと思っています。

jquery.bgpos.jsもできればない方ですと、非常に助かったりしますT-T

Syuji

caramelさん。

記事内に「下からスライド」バージョンを追加しましたのでお試しください。

東京ですか。イロイロ勉強出来そうでいいですねぇ。
沖縄はセミナーとかが乏しくて悲しいです。

caramel

ありがとうございます!ちょっと試してみます。
ちなみにFirefoxの5.01ではdemoが動作してなかったみたいです。
safariは動作してました。取り急ぎです。

沖縄はそうですよね、、紙とのハイブリッドのデザイナーなので、技術的な部分についてはまだまだ未熟で、、助けて頂いてますT-T

caramel

あ、ちなみにMac環境です。前回は動作してました。

caramel

たびたびすいません、DEMO環境のみ動作しないようです。
私の方のローカルでは、safari、firefoxともに動作しました。

Syuji

caramelさん。

MacだとDEMO動かないんですか。ご連絡ありがとうございます。
でも残念ながらMac環境で確認が出来ないんですよねぇ。
一応Windowsで確認すると動いたんですけど。

とりあえず動作したみたいで良かったです。

caramel

いえいえ、ありがとうございます。ローカルのMac環境では動いているので
多分大きな問題ではないかと思います。あ、DEMOはsafariは動いているので、
何なんでしょうかね、、でもこちらでは使えてるのでありがとうございます^^

Top