CSSでクラスを指定してそれらのデザインをごそっといじるという場面はよくある。
そのデザインを特定のイベントで変更したりするとき、クラス名でElementを取得するのに
getElementsByClassName("クラス名")
というものがある。
ところがこれはFirefox 3ではサポートされているがIEではUndefinedで返ってくる。
でも使いたいなーって時があったのでその時作ったクラスの覚え書き。
目的である「クラス名からエレメントを取得する」という動作を実現するには…
- 全要素を取得して一つ一つクラス名を検索対象のクラス名と比較する。
- クラス名が一致すれば配列に突っ込む。
- 全て終わったら出来上がった配列を返す。
という3ステップでできそう。
ならば…
function getElementsByClassName(targetClass){ var foundElements = new Array(); if (document.all){ var allElements = document.all; } else { var allElements = document.getElementsByTagName("*"); } for (i=0.j=0;i<allElements.length;i++) { if (allElements[i].className == targetClass) { foundElements[j] = allElements[i]; j++; } } return foundElements; }
こんな感じでできました。
重要なところにコメント。
function getElementsByClassName(targetClass){ var foundElements = new Array(); //見つかったエレメントを一時的にしまっておく配列 if (document.all){ //IEで全要素を取得する var allElements = document.all; } else { //それ以外での全要素取得 var allElements = document.getElementsByTagName("*"); } for (i=0.j=0;i<allElements.length;i++) { if (allElements[i].className == targetClass) { //全要素のクラスを検索クラス名と比較 foundElements[j] = allElements[i]; //見つかったものを配列の格納 j++; } } return foundElements; //全部終わったところで戻り値に配列を指定 }
といったかんじです。
果たして、ブラウザでもともとサポートされてるものと同じ関数名を付けて大丈夫なのかというのはわかりません。
もう一つ注意点としては、Firefoxでサポートされているものは
指定要素.getElementsByClassName("クラス名")
で指定要素の子要素の中で指定するクラス名のものを返す。
という便利機能が有りますが、今回作成したものではそれはできません。
あくまでDocumentの全要素からの検索になります。
これに指定要素以下で働く機能をつけるにはどうしたらいいんだろう…それはちょっと難しそう。
しかしこれで簡易的には
getElementsByClassName("クラス名")
をIEで使うことができます。
Android搭載デバイスやiPhoneなどモバイル端末用のブラウザなども増え、クロスブラウザかつギミックたっぷりなWebページを作るのは難しい環境ですね~
全ての要素にプロトタイプで渡すとか