JavaScript勉強会「コードの力を引き出す、自分ライブラリの作り方」

こんにちは。エンジニアの川島です。
先日、私たちは、社外から技術顧問の方をお招きし、JavaScriptのオンライン勉強会を行いました。
今回の勉強会の目的は、日々積み重ねてきたJavaScriptのコードを活かし、オリジナルのライブラリを作ること。有用なアドバイスを多くいただいたので、皆さまにもご紹介したいと思います。

はじめに

外部ライブラリやフレームワークを入れるほどではないけれど、標準的に使うことが多い、ちょっとした機能——スムーズスクロールや、固定ヘッダー/フッターの表示切り替え、ボタン押下でのclass付け外しなど——皆さまは、どのように実装することが多いでしょうか。

これらは流用が効くコードのため、案件ごとに0から書くという機会は少ないかと思います。もっとも単純な方法としては、たとえば、他案件のコードをコピー&ペーストして案件ごとにカスタマイズする運用が挙げられます。

ですが、流用コードを毎回のようにカスタマイズするのは、ちょっと面倒です。案件の数や、開発に関わるメンバーが増えれば尚のこと。
そこで今回の勉強会では、流用コードの汎用性を高め、ライブラリに作り変える知見を教えていただきました。

既存コードの汎用性を高めるには

ライブラリ化にあたって重要なポイントは、既存のコードを汎用性ある形に書き換えることです。
たとえば、下記のようなコードを案件ごとにカスタマイズして利用しているとします。
スクロール距離によってclassの付け外しを行う、シンプルな関数です。

このコードを利用する場合のファイル構成は、以下を想定しています。

  • index.html(jQueryと、案件ごとの.jsファイルを読み込む)
  • 案件ごとの.jsファイル

案件ごとにコードのあちらこちらを書き換えるのは、あまり汎用的とは言えません。(コードの値にHTML/CSS側を揃えるという手段もありますが、その場合はコーディング規約の策定と共有が必要になります。)
このようなコードを資産として活かすには、もう一工夫が必要です。

関数の引数を活用する

JavaScriptの関数は、引数を指定することで、汎用性を高めることができます。
案件ごとにカスタマイズしていた箇所で引数が利用できるよう、コードを書き換えてみましょう。1行目「function ()」のカッコ内に引数を追加し、固定値で記載されていた箇所はそれぞれ引数で置き換えます。

あとは関数を実行する際、引数にそれぞれの値を渡すだけ。
上記サンプルでは、引数targetは「今回の案件で使う要素」、class_nameは「今回の案件で使うclass名」、pos_hは「今回の案件で使うピクセル値」に対応しています。
先ほどの例のように、コード内の値を細かく書き換える必要はありません。他案件で使いたい場合は、22行目の引数の変更だけで対応することができます。

オリジナルライブラリの作り方、使い方

さて、引数を利用することでコードの汎用性が高まり、様々な案件で使いやすくなりました。
これらをまとめて、オリジナルのライブラリにしてみましょう。
基本的な考え方は以下のとおりです。

  1. 共通で利用する機能(関数)を、ライブラリとして一つの.jsファイルにまとめる
  2. 案件ごとの.jsファイルで、ライブラリ内の関数を呼び出し、引数を渡して実行する

ファイル構成は以下を想定します。

  • index.html(jQueryと案件ごとの.jsファイルに加え、オリジナルライブラリの.jsファイルを読み込む)
  • オリジナルライブラリの.jsファイル
  • 案件ごとの.jsファイル

上記を踏まえ、オリジナルのライブラリを利用したwebサイトのイメージを、codePen上に作成してみました。
Result画面を300ピクセル以上スクロールすると、ライブラリ内の関数によって、ヘッダーが固定表示に切り替わります。(※スマートフォンでは上手く表示されない場合があります。パソコンからご覧ください)

See the Pen オリジナルライブラリの作成サンプル by sayaka (@river_is_land) on CodePen.

HTMLタブで外部のライブラリを読み込み、JSタブで引数に値を渡して関数を実行しているのが分かるでしょうか。
このように、案件ごとの.jsファイルはシンプルな記述でライブラリの機能を利用することができます。

解説

案件ごとの.jsファイルでは、下記記述によってオリジナルライブラリ内の関数を実行しています。

NSW_EFFECTOR.initScrollerFix("#header","fixed",300);

そして、オリジナルライブラリ(nsw_effector_sample.js)の内部は、下記のようになっています。

引数によって、対象要素「#header」に、表示固定用class「fixed」を、「300」px以上スクロールされた場合のみ、追加するよう指定しています。
※なお、4行目の「window.NSW_EFFECTOR」は、ライブラリ外から関数を利用できるよう、意図的にグローバル関数を定義したことを示す記法です。参照:JavaScript応用編 – windowオブジェクトとグローバルの実態について

今回はサンプルのため、ライブラリ内には「NSW_EFFECTOR.initScrollerFix」一つしか関数を記述していません。
しかし、webサイトで汎用的に活かせる機能は、まだまだ沢山あります。
「NSW_EFFECTOR.initGnavBtn」等、ここから様々な関数を書き足してゆくことで、ライブラリを充実させてゆくことが可能です。

おわりに

webサイト制作にあたって、もはや不可欠なJavaScript。
便利なライブラリも数多く存在しますが、サイトによってはオーバースペックであったり、容量のために表示速度を圧迫してしまったりと、考慮して使わなければデメリットも存在します。
そんなとき、自分で書き溜めたコード資産をオリジナルのライブラリにしておけば、必要な機能だけを使うことができ、より効率的なサイト制作の助けになるかと思います。