はじめての javascript・jQuery - 続・ロールオーバー画像切替え split(), slice() 編

前回の はじめての jQuery - ロールオーバー画像切替え から少し変更してみた。

HTML

<!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" xml:lang="ja" lang="ja">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <title>はじめての javascript・jQuery - 続・ロールオーバー画像切替え split(), slice() 編</title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="rollover_img.js"></script>
  </head>
  <body>
    <ul id="menu">
      <li><a href="/"><img src="img/btn_menu_hoge_over.jpg" alt="ほげ" /></a></li>
      <li><a href="/"><img src="img/btn_menu_fuga.jpg" alt="ふが" /></a></li>
      <li><a href="/"><img src="img/btn_menu_hige.jpg" alt="ひげ" /></a></li>
    </ul>
    <div id="body">
      (略)
    </div>
  </body>
</html>

メニュー(<ul id="menu">)の画像をマウスオーバー、マウスアウトで切り替わるようにします。画像のファイル名は以下の様に、通常時のファイル名に何がしかの接尾語(この場合「_over」)をつけたものにします。

  • 通常(マウスアウト):***.jpg
  • マウスオーバー:***_over.jpg

勿論、画像形式は jpeg 以外でも大丈夫です。接尾語も適当なものを使用できますが、画像の src 属性値に同じ文字列が無い様にする必要があります。

split() 編

split メソッドは、文字列を指定した文字列で区切り、区切られた文字列を格納した配列を返します。各値に区切り文字は含まれません。
参考)http://developer.mozilla.org/ja/docs/Core_JavaScript_1.5_Reference:Global_Objects:String:split

$(document).ready(function(){
  function rollover_img(selector, suffix){
    $(selector).each(function(i){
      var default_img = $(this).attr("src"); //画像要素の初期src属性値
      if (!default_img.match((suffix))) { //src属性値に接尾語がついていた場合は動作させない
        var string_list = default_img.split("."); //src属性値を拡張子の.(ドット)で区切る
        var mouseover_img = string_list[0] + suffix + "." + string_list[1]; //接尾語を加えてマウスオーバー用のsrc属性値文字列を作成
        var preload_img = new Image();
        preload_img.src = mouseover_img;  //マウスオーバー用画像を読み込み
        $(this).hover(
          function(){
            $(this).attr("src", mouseover_img);
          },
          function(){
            $(this).attr("src", default_img);
          }
        )
      }
    })
  }

  rollover_img("#menu img", "_over");  //画像のセレクタと接尾語を引数にして関数を呼び出す
});

マウスオーバー用の src 属性値文字列を作成する際、通常時の src 属性値を .(ドット)で区切る為、src 属性値に拡張子以外のドット(../ など)がある場合は正しく動作しません。
対応策として、以下の様に slice() を使用してみました。

slice() 編

slice メソッドは、文字列から始めと終わり(省略可)のインデックスを指定し、指定した範囲の文字列を返します。終わりのインデックスを省略した場合、文字列の最後までの指定になります。
参考)http://developer.mozilla.org/ja/docs/Core_JavaScript_1.5_Reference:Global_Objects:String:slice

$(document).ready(function(){
  function rollover_img(selector, suffix){
    $(selector).each(function(i){
      var default_img = $(this).attr("src"); //画像要素の初期src属性値
      if (!default_img.match((suffix))) { //src属性値に接尾語がついていた場合は動作させない
        var point = default_img.lastIndexOf(".") //src属性値の拡張子の.(ドット)の位置
        var mouseover_img = default_img.slice(0, point) + suffix + default_img.slice(point); //接尾語を加えてマウスオーバー用のsrc属性値文字列を作成
        var preload_img = new Image();
        preload_img.src = mouseover_img;  //マウスオーバー用画像を読み込み
        $(this).hover(
          function(){
            $(this).attr("src", mouseover_img);
          },
          function(){
            $(this).attr("src", default_img);
          }
        )
      }
    })
  }

  rollover_img("#menu img", "_over");  //画像のセレクタと接尾語を引数にして関数を呼び出す
});

lastIndexOf メソッド を使用して拡張子の位置を調べ、その直前に接尾語を加えている為、拡張子が無い場合と、拡張子の後にドットがある場合は正しく動作しません。

おわりに

ほぼ当初に想定した形になりました。画像のプリロードのところに若干微妙な印象を持たなくもありませんがよく分かりません。
一般的な用途にはこれで間に合うと思いますがどうでしょうか。