JavaScript : Internet Explorer 8 で getElementsByClassName を使う
2013.09.20
・document.getElementsByClassName - Web API リファレンス | MDN
getElementsById や getElementsByTagName を使ってページを走査し、特定の要素を抽出してJavaScriptを適用する方法が有りますが、同じclass名持つ複数のdiv要素に対して一斉にJavaScriptを適用したい場合には、getElementsById や getElementsByTagName では要素の特定に必要な処理が増えてコードも冗長的になってしまいます。
IE8 と getElementsByClassName
HTML5で追加された getElementsByClassName を使えばこの問題がスッキリ解決するのですが例のごとくIE8以下では使えません。
HTML5に対応したFireFox ,Sfari,Chrome,Opera,IE9 であれば問題ありませんが、XPのサポート終了後も全てのXPがWindows 7や8、もしくは8.1に一気に変わる事は考えにくいので、当面はIE8もブラウジング対象のブラウザとして含める事になりそうです。
かと言って過去のモノとなるのが既に決まっているIE8の為に getElementsById や getElementsByTagName を使ってダラダラと長いコードを書くのも何だし 『何か良い方法は無いかなぁ・・・』 と検索してみたら jQuery を使う以外でも方法が有りました!\(^o^)/
・getElementsByClassNameメソッド - JavaScript ライブラリー - HTML5.JP
このライブラリを組み込めばアンダー Internet Explorer 8 でも getElementsByClassName が使えるようになります。
使い方は特に難しくは無いのですが、getElementsByClassName の出番が一番多いと思われる <div> 要素を対象にコードを書いてみました。
最近はフラットデザインが流行っているようなので、リキッドレイアウトのページ上で正方形のグリッドを配置し、ブラウザのサイズが変わるとページ内の正方形サイズも追従するようにしてみました。単にCSSで<div>の縦横サイズを固定すれば良いのですが、リキッドレイアウトでグリッドサイズも可変にするとなるとJavaScriptで制御するのが一番簡単かなと…。
上記リンク先ページはIE8でもgetElementsByClassNameが動作する事が確認できます。(もちろんHTML5対応ブラウザもOK)
コードは下記になりますが、将来IE8が消滅した後でも1行を修正(削除)すればそのままコードが使えます。
js_classname_sample.html : CODE
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>getElementsByClassName サンプル</title> <!--[if lte IE 8]><script type="text/javascript" src="dom/getElementsByClassName.js"></script><![endif]--> <style> h1 { margin-bottom: 50px; } #wrap { width: 100%; margin-right: auto; margin-left: auto; position: relative; text-align: center; } .grid { float: left; border: 1px solid #0000FF; margin-left: 3%; margin-bottom: 3%; } </style> </head> <body> <h1>getElementsByClassName サンプル</h1> <div id="wrap"> <div class="grid">Square 1</div> //全て同一のclass名 <div class="grid">Square 2</div> <div class="grid">Square 3</div> <div class="grid">Square 4</div> <div class="grid">Square 5</div> <div class="grid">Square 6</div> <div class="grid">Square 7</div> <div class="grid">Square 8</div> </div> <script> box_resize(); window.onresize = box_resize; function box_resize() { if (document.all) { w = document.body.clientWidth; //表示領域の横幅取得(px) ※スクロールバー領域含まず h = document.body.clientHeight; //表示領域の縦幅取得(px) ※スクロールバー領域含まず }else{ w = window.innerWidth; //表示領域の横幅取得(px) ※スクロールバー領域含む h = window.innerHeight; } var setWH = (w * 0.2)+'px'; //取得した表示領域横幅の20% var arr_obj = document.getElementsByClassName('grid'); //<div>:class取得 for( i=0; i< arr_obj.length; i++ ){ arr_obj[i].style.width = setWH; //対象<div>:width に横幅を適用 arr_obj[i].style.height = setWH; //対象<div>:heightに横幅を適用 } } </script> </body> </html>
解説・注意点
コードのポイントなど・・・(´・ω・`)
IE8に対応させる
<!--[if lte IE 8]><script type="text/javascript" src="dom/getElementsByClassName.js"></script><![endif]-->
IE8以下の場合のみ getElementsByClassName.js をloadする設定ですが、パスは各々のディレクトリ構造に合わせて修正して下さい。
将来的にIE8をブラウジング対象から除外する場合はこの一行は不要となります。
CSS
.grid {
float: left;
border: 1px solid #0000FF;
margin-left: 3%;
margin-bottom: 3%;
}
表示領域に追従・連動してサイズが変動する div要素のCSS設定
ブラウザの表示領域取得
スタイルシートは通常の書き方と変わりませんが、リキッドレイアウトで各要素がサイズ可変となる様に対象のサイズ、位置はpxではなく%単位で指定します。今回、div要素のCSS(width・height)プロパティをJavaScriptで書き換えるのですが、予めCSSでW・Hサイズを指定しておく必要は有りません。
if (document.all) { w = document.body.clientWidth; //表示領域の横幅取得(px) ※スクロールバー領域含まず h = document.body.clientHeight; //表示領域の縦幅取得(px) ※スクロールバー領域含まず }else{ w = window.innerWidth; //表示領域の横幅取得(px) ※スクロールバー領域含む h = window.innerHeight; }
ここでもInternet Explorerの呪縛が・・・
IEの標準モードがウンたらカンたら…詳しくは検索して下さいw
要は特定のブラウザ環境では表示領域サイズが取得出来ないので条件分岐しています。
また、今回の例ではブラウザの横方向サイズを基準として正方形を描画するので、縦方向サイズ情報の取得は必要無いのですが、長方形とする場合は必要となるかもしれません。まぁ、気は心という事で・・・(何だソレw)
要素のサイズ指定
var setWH = (w * 0.2)+'px'; //取得した表示領域横幅の20%
取得したブラウザの表示領域の20%をdivのW・Hサイズとします。(今回は単位を【px】としています)
このサイズもデザインに合わせて調整しますが、各div要素のマージンも考慮し調整して下さい。
getElementsByClassName
var arr_obj = document.getElementsByClassName('grid'); //<div>:class取得 for( i=0; i< arr_obj.length; i++ ){ arr_obj[i].style.width = setWH; //対象<div>:width に横幅を適用 arr_obj[i].style.height = setWH; //対象<div>:heightに横幅を適用 }
ページ内に存在する class名=grid を持つ要素を全て取得し、for文でブン回して先に決定したW・Hサイズを適用します。
今回のサンプルでは1行につき4個のdiv要素を並べていますが、divのサイズを可変にしつつ1列の個数も変えたい場合は、もう一工夫必要となります。
そもそもリキッドレイアウトにしたからdivのサイズも可変にする必要があるのか?というツッコミは無しで・・・(´・ω・`)