48日目 入力コメントをajaxで送信⑤($(function() {...}) の意味)
おはようございます。今日もnoteを書いていきます。
これまでの取り組みは以下にまとめてあります。
現在、コメントを入力した内容をajaxで送信して、データベース上へ登録できるように取り組み中を用いており、jqueryを利用しています。(JRuby on Railsで開発中です。)
昨日はjqueryを用いて、テキストエリアのキーボートイベントを取得するイベントを以下のように定義していました。(「chat.js」というjavascriptファイルで以下の1~5行目を記述)
1 $(function(){
2 $('textarea[name="comment"]').keydown(function(event) {
3 console.log(event.key);
4 });
5 })
ただ、昨日にnoteで記事を書いていたとき、その記事にてjqueryを用いてjavascriptファイルへ内容を追記する際、追記内容の2~4行目については説明しましたが、1行目の『$(function() {』についてはまだ説明していませんでした。※1行目の『$(function() {』のカッコの始まりは、5行目の『})』に対応しています。
この1~5行目の『$(function() {...})』については意味があります。
以下の記事にも詳しく説明がありますが、今回の記事でも自分への備忘録も兼ねて説明します。
『$(function() {...})』とは、該当するHTMLファイルの最後まで読み込んでから『$(function() {...})』の『{…}』部分が実行されるようにする、という意味があって実行するタイミングを遅らせる効果があります。
どんな効果があるのか、できるだけ詳細に説明を残します。今回の場合、Rails上で定義したHTML部分(chatコントローラーのindexアクションに対応するview「index.html.erb」)の内容は以下のコードの通り、自分で作って定義はしていますが、
1 <div class = "real_chat">
2 <div id = "free_space">
3 <div id = "input_area">
4 <textarea name="comment"></textarea>
5 </div>
6 </div>
7
8 <div id = "history_space">
9 <div id = "output_area">
10 <table id = "result">
11 </table>
12 </div>
13 </div>
14 </div>
実際には、上記の内容がそのままHTMLファイルとなるわけではなく、その他のHTMLのテンプレートや、CSSやJavascriptファイルへのリンクも、Railsの方で色々と一緒に組み込まれて、1つのHTMLファイルができあがります。
実際のHTMLファイルの内容がどんな感じになるのかというと、例えば、Railsアプリケーションを起動した状態で、以下のようなチャット用の画面があったとして、
以下の①と②の操作を行なうと、
以下のようにずらっとHTMLの各種タグが並んだものが表示されます。
上の図では文字が小さくて見づらいのでもう少し拡大すると、以下のようにAssets(cssファイルやjavascriptファイル)への各種リンクが定義されている前半部分(3~16行目)と、HTML(chatコントローラーのindexアクションに対応するview「index.html.erb」で記述した内容)の定義がある後半部分(17~34行目の)の2つに分けることができます。
ここで、その前半部分に注目してみます。前半部分の中に「chat」という「chat.js」と同名のものが含まれている行のリンクがあると思いますが、そのリンクをクリックしてみてください。
上のように、リンクをクリックすると「chat.js」で記述した内容と同じもののコードが以下の画面のように表示されます。
実は上記画面のURLは「http://localhost:3000/assets/chat.self-05b6f090e…」というように、「chat.self-」以降の文字列は色々な文字列(プリコンパイル時に毎回ランダムで構成される文字列)が続いていますが、その色々な文字列で構成されたURLにアクセスすると、「chat.js」のデータが格納されています。
そのため、「chat.js」で定義したコードの内容が読み出されるタイミングは、HTML(chatコントローラーの「index.html.erb」で記述した内容)の定義がある後半部分(17~34行目の)よりも先です。
言葉だけだとわかりにくいと思いますので、以下に補足説明を付けて図を入れてみました。
上の図にて何が言いたいのかというと、「index.html.erb」で定義した内容よりも、「chat.js」で定義した内容のほうが先にプログラムとして実行されるということです。
つまり、「chat.js」にて以下のコードがあって、2行目の一部に『'textarea[name="comment"]'』というようにHTMLの要素を指定している箇所がありますが、この『'textarea[name="comment"]'』は「index.html.erb」で定義されているものであり、「chat.js」が読み込まれた時点ではまだ読み込まれていないもので未定義のものです。
1 $(function(){
2 $('textarea[name="comment"]').keydown(function(event) {
3 console.log(event.key);
4 });
5 })
そのため、もし、1行目の『$(function(){』と5行目の『})』で囲んでおかない(実行するタイミングを該当するHTMLファイルの最後のほうへと遅らせておかない)と、『'textarea[name="comment"]'』は未定義の要素とみなされ、テキストエリアへの入力イベントを設定できません。
ですが、1行目の『$(function(){』と5行目の『})』で囲むことによって、実行するタイミングを該当するHTMLファイルの最後まで読み込んだ後へと遅らせることができ、『'textarea[name="comment"]'』が定義済の要素とみなされ、テキストエリアへの入力イベントを設定できます。
長々と説明しましたが、Rails上でjqueryを用いてプログラムを記述する際、基本的にはそのプログラムを全て『$(function() {...})』で囲んでおいたほうがよいということです。
そうすることによって、要素が未定義であったためにイベントを設定できないというプログラム上の不具合をある程度避けることができます。
おわりに
ここまで読んでくださってありがとうございました。
今回、作業はなく説明のみでしたが、備忘録として残したかったため、noteに記事を書きました。
次回はEnterキーを押した場合の動作についてコードが書ければと思います。
次回もよろしくお願いいたします。