ホームページ黎明期はトップページにFLASHを埋め込み「つかみ」の役割をしていました。
それも時代とともに、FLASHからJqueryへ役割が変化しました。
bxSliderは画像をスライドさせるJqueryプラグインで、トップページのつかみ部分によく利用されます。
手軽にビジュアル面を強調できるため、重宝します。
ところが今回次のような現象が発生しました。
「ページを開いたときにbxSliderの最後の画像から表示されることがある。」
という現象です。
必ず毎回発生するわけではありませんが、時たま発生します。
今回はこの現象について調査し、対処しました。
現象は次の通りです
- bxSliderで現象が発生
- 画像は5枚セット
- 普段は1枚目から表示されるが、現象発生時は5枚目から表示される
問題は現象が発生するときと発生しない時がある
現象が必ず発生する状況であれば、調査はやりやすいのですが、今回の現象は出るときと出ない時があります。
bxSliderはスクリプトなので、コードを追っていけばいずれ原因がつかめるかもしれません。
ただ、そのためにはいつ起きるかわからない現象をひたすら待つ必要があります。
さすがに時間がかかるので、まずはググって調べることにしました。
すると、気になる情報を見つけました。
それがこちらです。
$(function()は見切りスタートすることがある
今回のソースは以下の通りです。
$(function()
{
$("#eyecatch ul").bxSlider();
});
ありきたりな記述方法ですが、この記述だとHTMLの読み込みが終わる前にスタートすることがあるというものでした。
つまり、重たいつくりのページの場合、読み込みに時間がかかると現象が発生し、キャッシュ等のおかげで読み込みが早かった場合は、現象が起こらないということでした。
そこで次の記述に変えたところ、現象がぴたりと止まりました。
Jqueryの記述をon loadに変える
結論から申し上げますと、次の記述に変更することで現象が全く発生しなくなりました。
$(window).on("load", function()
{
$("#eyecatch ul").bxSlider();
});
Jqueryの最初の記述をon loadに変えただけですが、これだけで現象が改善しました。
せっかくなのでその理屈について調べてみました。
readyとon loadの違いについて
最初の記述である$(function() は、$(document).ready(function() の省略記述です。
意味的には「HTMLがready状態になったら動作」です。
それに対し、$(window).on(“load”, (function() はHTMLの読み込みが完了したら動作です。
一見どちらも同じ意味のように思えますが、詳しく調べてみると差異がありました。
それがこちらです。
$(document).ready(function() | HTMLのDOMの読み込みが終わったら動作 |
$(window).on(“load”, (function() | HTMLの全ての要素の読み込みが終わったら動作 |
なんかわかるようなわからないような。
DOMって何?
というわけで、さらにわかりやすく表現したものがこちらです。
$(document).ready(function() | HTMLのタグが読み込めたら動作する ※画像ファイル等の読み込みは待たない |
$(window).on(“load”, (function() | HTMLのすべてが読み込み終わるまで動作しない ※画像ファイル等の読み込みを待つ |
つまり、readyはon loadより先に動作します。
readyは、画像が読み込みできていなくても動作します。
bxSliderは画像の要素についても操作するため、画像読み込み完了前に動作すると誤動作する可能性があります。
だから、現象が発生したり、しなかったりしていたのです。
それに対し、on loadは画像の読み込みが完了してから動作するため、現象が発生しなくなったのです。
詳しく調べてみると、なるほどと思える答えにたどり着きました。
ちなみにDOMとはJavascriptが動作するためのAPI(機能)です。
DOMは、タグが読み込み完了していないと誤動作します。
readyとは、DOMが動ける状態になったら動作という意味なのです。
だったら全部 on loadでいいのでは?と思いますが・・・
Jqueryの読み込みタイミングで誤動作するのであれば、全部on loadにすればいいのではないか?
とも思われます。
ただ、これはケースバイケースとも言えます。
例えば、ナビゲーションや、スマホのメニューボタンなど画像とは関連しないスクリプトに対してon loadを使用すると、ちゃんと動作していない状態が一瞬見えることが起こります。
この場合は、readyのほうが良いといえます。
なので目安としては次の通りになるといえます。
- 普段はreadyを使用する
- 画像や外部情報を使用する場合はon loadにする
そういえば、以前の記事で同様のことも書いていました。
この時は、iframeの高さを調整するために、読み込み先のHTMLの高さを求めるというスクリプトを作っていましたが、readyだとiframeに記述したHTMLを読み込む前に作動してしまい、正しく動かないというものでした。
ちょっと悩みどころですが、状況に併せて使い分けることが肝要です。
わかりにくいものほどよく確認
私は、PHPはよく使用しますが、Javascriptはそこまでではありません。
今回調べていて、普段耳にしないようなことも多くあり、用語などをさらに調べました。
Javascriptは元をたどればC言語に準拠している部分が多いですが、PHP等他の言語と比べると少々独自性が強く、不可思議な理屈も多いです。
そのため、現象が発生したり、しなかったりとあいまいな状況も起きます。
だからこそ、普段より良く調べることが大事であると思いました。
忙殺状態だと、つい「後回し」ということも起こりがちですが、後々それが問題になることもあります。疑問は早めに解決することが大事です。