jQueryでCSSのスタイル操作をする際に注意すべき実行タイミング

フロントエンド
エンジニア

カナちゃん

はじめまして!
ロジカルスタジオPR部のカナちゃんです。

今年の春から新卒で入社しました。

特技は指の第一関節だけ曲げることですが、まだ業務で生かせたことはありません。

jQuery実装の際、中身は合っているはずなのに思い通りに動かず困った経験はありませんか?

ちなみに私はあります。(記述が間違っていることがほとんどですが…)

そんな問題を解決できるかもしれない、jQueryの実行タイミングの話をします。

今回の記事で登場する専門用語の解説をしておきます。

DOMとは「Document Object Model」の略です。

DOMとはHTML  XML 文書を操作するための、たくさんの機能や規則のこと。」と言えます。

出典 Watablog

HTMLパースとは、HTML文法規則にのっとった文字列を、その文法に基づいて字句解析し、意味や構造を解釈することをいい、HTMLパースを行うプログラムのことをHTMLパーサといいます。

出典 SEO検索エンジン最適化

失敗例

HTMLでヘッダーの下に表示されるメガメニューを作り、jQueryの中にCSSを記述しました。

<head>
 <script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
</head>
<body>
 <script src="js/megaMenu.js"></script>
</body>
/* メガメニュー */
$(window).on("load scroll resize", function () {
 // jQueryでCSSを操作
});

上記のように作ったWebサイトのチェックを行なっていたところ、一部ブラウザで、jQueryで書いたCSSが反映されず、表示が崩れることがありました。

表示が崩れた理由

先にDOMが構成され、その後にjQueryが実行されていたため表示が崩れてしまったようです。

つまり、jQueryを実行するタイミングを早めてあげれば解決です。

今回行った対応策について解説していきます。

<script>タグのasync、defer属性

<script>タグにはasync、deferという属性を指定することができます。

この属性を付けることで、scriptの読み込み方を変えることができます。

  • default(指定なし)
    HTMLパースを中断してscriptをダウンロード・実行する(同期的処理)
  • async、defer
    HTMLパースと同時進行でscriptをダウンロードする(非同期処理)

「async」や「defer」属性は、HTMLパースと同時進行(非同期)でscriptのダウンロードまでやってくれるので、

デフォルトに比べると、全体的に読み込み速度が早くなります!

※JavaScriptでdocument.write()メソッドを使用している場合は使用することはできません。

デフォルトでは、DOMに影響を与えるdocument.write()メソッドの記述があるかを調べるために、HTMLパースを中断しています。

async、defer属性はdocument.write()メソッドを無視する代わりに、HTMLパースを継続することができるためです。

そうすると次は、

asyncとdeferは何が違うの?

結局どっちが早いの?

などといった疑問が出てくるかと思うのですが、scriptの内容によって使い分ける必要があります。

async

scriptのダウンロードが終わり次第、記述順関係なく実行します。

jQueryなどの依存するライブラリを使用していない場合に使います。

<head>
 <!-- 使用例 -->
 <script src="js/scroll.js" async></script>
 <script src="js/pagetop.js" async></script>
</head>

defer

scriptを上から記述順に読み込んで実行します。

外部のライブラリを使用している場合や、依存するscriptファイルを上から順に記述している場合に使います。

<head>
 <!-- 使用例 -->
 <script src="https://code.jquery.com/jquery-3.3.1.js" defer></script>
 <script src="js/modal.js" defer></script>
</head>

修正点

<script>タグにdefer属性を指定し、<head>内に移動

<head>
 <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
 <script src="js/megaMenu.js" defer></script>
</head>

先ほど説明したように、scriptタグにdefer属性を追加します。

今回はmegaMenu.jsの中身をjQueryで記述していたため、deferを指定しました。

終わりに

実行タイミングについて見直すことで、jQueryの挙動を安定させることができました。

jQueryやJavaScriptのブラウザ動作で困った方は、一度見直してみてはいかがでしょうか?

ロジカルスタジオで働くタイミングは今しか無いかもしれません!あなたのキャリアも見直してみませんか?興味のある方はコチラから↓

ロジカルスタジオ 採用サイトはこちら