jQueryで処理されるタイミング 【div箱の高さが取得できない!の原因1】
jQueryで、ページ読み込み完了後に仕掛けをする事がよくある。
私は初めて「表示後にdivボックスの高さを調整しようとする処理を追加した」時にハマった。
$(document).ready(function(){ /* 処理 */ });
$(window).load(function(){ /* 処理 */ });
といった指定で、プログラムを走らせるタイミングを計る。
このタイミングを間違えると、ブラウザが意図する動きをしてくれない。
ボックスの高さがうまくそろわない原因は他にもあるのだが、今回はjQueryの処理実行のタイミングについての話で、自分がWEB制作に取り組むときにお約束で記述するjavascriptを紹介する。
$(document).ready | HTML(DOM)読込直後
$(document).readyは、そのページのHTML(DOM)が読み終わった直後に実行される関数。
省略されて記述される事も多く、次の3つの指定はいずれも同じ意味になる。
<script> $(document).ready(function(){ /* 処理 */ }); $(function(){ /* 処理 */ }); /* 以下、非推奨ですが、動きます */ $().ready(function(){ /* 処理 */ }); </script>
『HTML(DOM)が読み終わった直後』なので、例えば、ページのHTMLにテキスト文を追加したり、各タグにclassなどを追記したりする処理を書いたりするのは問題ない。
一番ハマる事が多いのが、ボックスの高さ取得したいと思った時。
ページのHTMLは読み込み完了しているが、配置した画像などのデータの取得は完了していない。imgタグでwidthやheightをきちんと指定していない場合は、その画像のサイズはわからない(たぶん高さも幅も「0」の扱い)ので、親となるボックスの高さも、思っている数値が取得できない。
つまり、
var h = $('div .classname').height();
var w = $('div .classname').width();
としても、正しいあたいは取得できない。
jQueryで画像やボックスの高さ・幅がうまく取得できない時には、最初にこの取得するタイミングはどこになっているのかをチェックすると解決する事がよくある。
$(window).load | ブラウザで表示された直後
$(window).load は、DOM要素の準備完了、つまり、ブラウザが表示をした後に処理される。
jQueryを使用しなくてもJavaScriptのwindow.onloadを使っても同じ様な処理が可能だが、他のもjQuery使っているわけなので、私は $(window).load を使うようにしている。
次の2つの指定は、いずれも同じ意味だと思っていいが、混在させることはしない方がいい(window.onload が無視されたりする)。
<script> $(window).load(function(){ /* 処理 */ }); window.onload(function(){ /* 処理 */ }); </script>
一旦ブラウザが出力した直後に実行されるので、先の例で述べた「配置画像のサイズがうまく取得できない」という事がなくなる。(ブラウザに表示されている = 表示されている幅も高さも取得できる)
ネットを見ていると、ページが表示された後に画面がチラついたり(パーツが消えたり動いたり)するのは、ここで修正処理がかかっている事が要因である。
繰り返しになるが、ここで各要素の値の調整を行った場合、表示後に再度表示が修正される事になるからだ。
画面サイズ変更時(リサイズ時)
「リサイズ」とは、例えばパソコンで閲覧していて「ちょっとはじっこにちっちゃく表示させておく」「おっきくして見る」といったユーザーの操作。
ブラウザの表示サイズが変更されたりした時に処理を施したい場合は、次の様に記述する。
<script> var timer = false; /* グローバル変数 */ $(window).resize(function() { if(timer !== false){ clearTimeout(timer); } timer = setTimeout(function() { /* 処理をここに書く */ }, 200); }); </script>
あまり深く考えずに、このまま使っていい。
気になるようであれば、動作に関して次のブログで紹介されているので、ご参考に。
http://kadoppe.com/archives/2012/02/jquery-window-resize-event.html
スマートフォンの縦横回転時
あまり使いませんが、スマートフォンの縦横回転時に処理をさせたい場合は、こんな感じで仕掛けます。
<script> $(window).on(“orientationchange resize”,function(){ /* 縦横問わず、画面が回転した時に実行する処理 if(Math.abs(window.orientation) === 90) { /* 縦 → 横 に回転した時に実行する処理 } else { /* 横 → 縦 に回転した時に実行する処理 } }); </script>
まとめ
WEB制作にかかる時、最初にJavaScriptを記述する時には、(処理があろうが、無かろうが)とりあえずここから始めるようにしている。
<script> $(document).ready(function(){ /* 処理 */ }); /* ページ読み込み後 **************/ $(window).load(function(){ /* 処理 */ }); /* ページ表示後 ****************/ var timer = false; $(window).resize(function() { if(timer !== false){ clearTimeout(timer); } timer = setTimeout(function() { /* 処理をここに書く */ }, 200); }); </script>
また、できるだけ処理を個別に記述するのではなくて、functionを作って、その関数を処理するようにしている。