無駄と文化

実用的ブログ

【jQueryの基本の"き"】パート2 - 起動スクリプトを詳しく解説

前回はjQueryプラグインを設置するための基本的な流れを解説しました。
今回はプラグインを使いこなすための要(かなめ)になる 起動スクリプト についてイメージしやすい例で解説していきます。


起動スクリプトとは

前回解説しましたが、jQuery本体やプラグインのJSファイルは通常、ページに読み込んだだけでは何も動作しません。
window にロードされて使える状態になってはいるものの、ページには何も影響を与えないわけです。

そこで、実際にjQueryプラグインを有意義に使うために 起動スクリプト を書く必要があります。


Slick というjQueryプラグインでは、こんな感じの起動スクリプトを書くだけでただの <ul> が写真めくりボタン付きのカルーセルに変身します。

<script>
jQuery(function($) {

  // ↓これが 起動スクリプト だ!
  $('.slides').slick({
    autoplay: true,
    prevArrow: '<button type="button" class="slick-prev">前へ</button>',
    nextArrow: '<button type="button" class="slick-next">次へ</button>',
  });

});
</script>

JavaScript を書き慣れない人にとっては、ただの記号の並びに見えてしまうかもしれません。
大丈夫、jQueryプラグインの起動スクリプトにはよく見かける鉄板のパターンがあります。鉄板パターンさえ押さえればいいんですよ。


起動スクリプトはどんな形をしているか

よく見かける鉄板パターンとは、前回も使ったこの画像に書かれているパターンです。

f:id:todays_mitsui:20160826230324p:plain

いかがです?
ポイントは起動スクリプトを3つのステップに分解して見てみることです。


ステップ1. 対象の要素を選択する

ステップ1はプラグインの対象を選んであげることです。
対象を指定する方法は簡単、Web畑の人間であれば慣れ親しんでいる CSSセレクター を使うことができます。

例えば、こんな感じの HTML があったとして、

<div class="container">
  <header>
    <h1 class="main-title">タイトルテキスト</h1>
    <p class="sub-title">Yet another タイトルテキスト</p>
  </header>

  <main>
    <section class="entry">
      <h2>記事のタイトル</h2>
      <article>
        <p>ここにテキストが入ります</p>
      </article>
    </section><!-- /.entry -->

    <section class="entry">
      <h2>二つめの記事タイトル</h2>
      <article>
        <p>ここにもテキストが入ります</p>
      </article>
    </section><!-- /.entry -->
  </main>
</div><!-- /.container -->

この中で、タイトルテキストのh1要素をjQueryで選択してみましょう。
なぁに、むつかしく考える必要はありません。jQueryのことはいったん忘れて、「このタイトルテキストの色を赤に変えて」と言われていつもの CSS を書く時のことを思い浮かべればいいんです。


きっとこんな感じになりますよね。

<script>
$('.main-title')
// => タイトルテキストのh1要素が選択されている
</script>

h1要素には偶然にも “main-title” というclass名がついていたのでそれを利用しました。
$() というのが対象を選択してくれる便利なやつです。
$ って何でしたっけ? そう、jQuery の別名ですね。jQueryにCSSセレクターを渡すとその要素を選択してくれます

セレクターの書き方ですが、もちろんタグ名を使って、

<script>
$('h1')
// => タイトルテキストのh1要素が選択されている
</script>

と書いたり。

合わせ技で、

<script>
$('h1.main-title')
// => タイトルテキストのh1要素が選択されている
</script>

と書いてもオッケィです。


さらに、CSS で複数の要素にスタイルを適用するときのように、1つのCSSセレクターで複数の要素を選択することもできます。

先ほどの HTML には記事の本文らしきp要素がふたつありましたね。
捕まえてみましょう。

<script>
$('.entry p')
// => 記事の本文(2つある!)の全てが選択されている
</script>

今回は「class=“entry” の内側にあるp要素」といった指定の仕方をしました。
その他、CSS3を含めたあらゆるセレクター :nth-child(odd)div > p やそれらの組み合わせも問題なく認識してくれます。

CSSセレクターさえ知っていれば、要素の選択は恐るるに足らずですね。


ステップ2. 適用するプラグイン名を選ぶ

要素を選択したら、その後に ドット. を繋いでプラグイン名を続けます。
前回使った Slick であれば .slick を続けて書きます。

<script>
$('.entry p').slick
// => 選択した要素に対して "Slick" を使うぞ!という意思表示
</script>

プラグイン名は大体公式サイトの目につくところに書いてあるはずなので、それをコピペなりしてください。

その他に、jQuery標準の機能も同様に書くことができます。
例えば対象要素の CSS を書き替える機能はズバリ .cssです。そのままですね。

<script>
$('.entry p').css
// => 選択した要素の CSS を書き替えてやるぞ!という意思表示
</script>

簡単ですね。これでもう8割がた終わってます。


ステップ3. プラグインにオプションを指定する

先ほど、ドット. に続けてプラグイン名を書きましたが、これだけではまだプラグインは発動しません。
あくまでも意思表示して構えただけです。引き金を引くのはこれから。

最後の仕上げでプラグイン名の後ろに 丸カッコ() を付けましょう。

<script>
$('.entry p').slick()
// => 丸カッコ() を付けた瞬間プラグインが発動します。引き金を引くような感覚ですね
</script>

ご存知のとおり丸カッコの中にはオプションを書き込むことも出来ます。
出来ますが、仮にオプションを書かない場合でも丸カッコだけは書かなければいけません。
丸カッコを省略してしまうと 何も起こりません

オプションを渡してみましょう。前回も書いた {autoplay: true} というオプションを書き込みます。

<script>
$('.entry p').slick({autoplay: true})
// => オプションを渡した書き方
//    コロン: で区切って左側がオプション名、右側がオプションの値
</script>

これにて Slick は私たちの意志を察して オートプレイ(ボタンを押さなくても一定時間で写真をめくる動作) をしてくれるようになります。



さて、ここまででjQueryの起動スクリプトを3ステップに分けて解説してきました。

  1. $() で対象の要素を選択して
  2. 適用するプラグイン名を ドット. で繋いで
  3. オプションを渡しつつ 丸カッコ() を付ける
    (オプションが無くても () は絶対に付ける!)

たったの3ステップ。簡単ですね。


ところでWeb畑にお住まいのみなさん、この3ステップ、何かに似ていませんか?

そう、イラレこと Adobe Illustorator の使い方にそっくり ですよね。


「jQuery = イラレ」仮説

と言うわけで、jQuery と イラレ がどんだけ似ているか証拠VTRをお見せしましょう。

私、先ほど「jQuery標準機能で要素のCSSを書き替えられる」って言いませんでした?言いましたよね。
ご覧下さい。

1. 対象の要素を選択して

f:id:todays_mitsui:20160827011510p:plain

2. 適用する機能を選んで

f:id:todays_mitsui:20160827011515p:plain

3. オプション(背景色)を指定しつつ実行

f:id:todays_mitsui:20160827011521p:plain


これをjQueryでやると…

<script>
// ↓1. 対象の要素を選択して
                //↓2. 適用する機能を選んで
$('div.square01').css({
  backgroundColor: 'rgb(100,220,150)'
});
// ↑3. オプション(背景色)を指定しつつ実行
</script>

完全に似てる。


ついでに先ほど「複数の要素を選択できる」とも言いませんでした?言いましたね。
はい、どうぞ。

1. 複数の対象の要素を選択して

f:id:todays_mitsui:20160827011529p:plain

2. 適用する機能を選んで

f:id:todays_mitsui:20160827011536p:plain

3. オプション(今度はボーダー色)を指定しつつ実行

f:id:todays_mitsui:20160827011545p:plain


jQueryだと…

<script>
// ↓1. 複数の対象の要素を選択して
                            //↓2. 適用する機能を選んで
$('div.square02, div.circle').css({
  borderColor: 'red'
});
// ↑3. オプション(ボーダー色)を指定しつつ実行
</script>

完 全 に 一 致 。


そんなわけで、イラレを使いこなしているWeb畑の人たちは無意識のうちにjQueryをマスターしていると言っても過言ではない(過言ではある)んです。

記号の並びにしか見えなかった起動スクリプトに親しみが湧いてきましたよね?


起動スクリプトを囲っている アレ をひもとく

ところで、いちばん最初に登場したきり軽やかにスルーされている、こちらのよく見る記述も気になりますよね?

<script>
// ↓よく見る・気になるこの記述
jQuery(function($) {

  /* ここに起動スクリプトが書かれていた */

});
</script>

コレについても全力で解説したい気持ちはやまやまですが、コレについては次回(パート3)に続けさせてください。


まとめ

今回は記号の並びにしか見えなかった起動スクリプトに親しみを持ってもらうために、イメージをかき立てる解説をしてきました。
簡単にまとめると、

  • 起動スクリプトは「1.対象選択」「2.プラグインを選ぶ」「3.オプションを渡しつつ実行」の3ステップ
  • jQuery と イラレ はめっちゃ似ている

というお話でした。


私からは以上です(続く)


【jQueryの基本の"き"】シリーズ

blog.mudatobunka.org

blog.mudatobunka.org

blog.mudatobunka.org

【jQueryの基本の"き"】 パート1 - jQueryプラグインの使い方

f:id:todays_mitsui:20160826221908p:plain


jQueryプラグインの 作り方 ではなく、使い方 です。
Web上には多くのjQueryプラグインが公開されていますが、どのプラグインにも共通する基本の使い方を解説します。

普段、サンプルコードをなんとなくコピペするだけで済ませてしまっている人も、基本さえ押さえればjQueryプラグインをもっと使いこなせるようになるはずです。


使ってみる

具体的にjQueryプラグインを何か使ってみながらの方がイメージしやすいと思いますので、今回はカルーセルを作るための有名なjQueryプラグインである slick を使ってみます。

完成イメージはこんな感じです。


ベーシックな使い方

jQueryプラグインを使うための大まかな流れをおさらいしておきましょう。
どのようなプラグインであってもだいたい以下の流れになるはずです。

  1. jQuery本体を読み込む
  2. jQueryプラグインを読み込む
  3. (プラグインに付属のCSSがあれば、)CSSを読み込む
  4. プラグインを適用する HTML を書く
  5. プラグインの起動スクリプトを書く


1. jQuery本体を読み込む

jQueryプラグインは、その名の通りjQueryの機能を前提として作られています。
なのでプラグインだけを読み込んでも動きません。まずはjQueryの本体を読み込みましょう。

公式サイトのダウンロードのページからjQuery本体をダウンロードしてきます。
今回はバージョン3系列の最新版をダウンロードして使ってみます。

jquery.com

ダウンロードしてきたら最低限の記述と <script> タグでjQueryを読み込んだだけの HTML を書きましょう。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta charset="UTF-8">
<title>Slick サンプルページ</title>

<link rel="stylesheet" href="./css/style.css">

<script src="./js/jquery-3.1.0.js"></script> <!-- JSファイルは <script> タグで読み込みます -->
</head>

<body>

<div class="container">
  <h1>Slick サンプルページ</h1>
</div><!-- /.container -->

</body>
</html>


さて、この HTML をブラウザで表示すると何が起こるでしょうか。
はい、何も起こりません。

jQueryを読み込むだけでは、表面上分かるような動作は何も行いません。
しかし、もしも貴方がブラウザのコンソールを開く方法を知っているならば、コンソールで以下の一文を実行してみて下さい。 (Google Chromeであれば、Ctrl+Shift+c または ⌘+option+j でコンソールが開きます)

jQuery().jquery

コンソールにjQueryのバージョン番号が表示されたはずです。
これでページの裏側で jQuery というオブジェクトが読み込まれたことが分かりました。

jQueryオブジェクトはページ上でHTMLを操作する便利な機能をたくさん詰め込んだオブジェクトです。
世の中にあるjQueryプラグインはjQueryオブジェクトの便利な機能を前提として、jQueryオブジェクトの機能をさらに拡張してくれます。


$ って何だろう

ところで、
ここでちょっと余談です。

jQuery関係でよく目にする $ という記号はいったい何者なんでしょうか?

$jQuery の別名です。 jQuery と6文字もタイピングするのが面倒な人のために、$ という記号を別名にしているんですね。

なので、

$('.foobar').fadeIn();

というように書いてある部分を、

jQuery('.foobar').fadeIn();

と書き換えても同じ意味になります。


2. jQueryプラグインを読み込む

次はjQueryプラグインの方を読み込んでみます。

今回は Slick を使うと言いましたね。こちらも公式サイトから最新版をダウンロードしてきましょう。 jQuery本体もプラグインも最新版を使う事で、バグが修正されたいちばんいい感じのものを使えるはずです。開発が活発なプラグインであれば毎月のようにバグ修正がされてバージョンアップされています。

kenwheeler.github.io

Slick は zip 形式で圧縮した状態で配布されています。
ダウンロードしたら zip を展開して、「slick.js」というファイルを見つけ出しましょう。

jQuery本体と同じフォルダに置き、先ほどと同じく <script> タグで読み込みます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta charset="UTF-8">
<title>Slick サンプルページ</title>

<link rel="stylesheet" href="./css/style.css">

<script src="./js/jquery-3.1.0.js"></script>
<script src="./js/slick.js"></script> <!-- 続けてプラグインも読み込みましょう -->
</script>

</head>

<body>

<div class="container">
  <h1>Slick サンプルページ</h1>
</div><!-- /.container -->

</body>
</html>


さて、先ほどと同じく HTML ファイルをブラウザで読み込ませて、何か変化がありますか?
またしても(表面上は)何も起こりませんね。

でもちゃんとプラグインが読み込まれているはずです。 コンソールに聞いてみましょう。

jQuery().slick

何か読み込まれている気配を感じ取れましたか?
実際に使ってみればもっと実感をもって感じられるはずです。続けましょう。


3. (プラグインに付属のCSSがあれば、)CSSを読み込む

プラグインによっては専用のCSSファイルが付属していることもあります。
モダンなWebサイトは HTML と CSS, JavaScript が3人4脚で働くので当然のことです。

Slick には「slick.css」という CSS が付属しているようです。お馴染みの <link> タグで読み込みましょう。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta charset="UTF-8">
<title>Slick サンプルページ</title>

<link rel="stylesheet" href="./css/style.css">
<link rel="stylesheet" href="./css/slick.css"> <!-- Slick に付属の CSS です -->

<script src="./js/jquery-3.1.0.js"></script>
<script src="./js/slick.js"></script>
</script>

</head>

<body>

<div class="container">
  <h1>Slick サンプルページ</h1>
</div><!-- /.container -->

</body>
</html>

CSS と JavaScript のどちらを先に読み込んでも構わないのですが、一般的にCSS を先に記述することが多いですね。


4. プラグインを適用する HTML を書く

さて、ここまでは下準備でした。
jQueryプラグインを使うのはここからです。

プラグインを適用する HTML を書きましょう。
何のタグを使ってどんな風に組めばいいでしょうか?こういうときは公式サイトを見るに限ります。
最も情報が正確で充実しているのは公式サイトなので積極的に見に行きましょう。

Slick でいえば、Getting Started のあたりに基本的な組み方が書いてある見たいですね。

では組んでいきます。
今回は猫の画像でカルーセルを作るので、<img> タグを並べましょう。

画像は Flickr からクリエイティブコモンズのライセンスがついたものをダウンロードして「img」フォルダに入れておきました。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta charset="UTF-8">
<title>Slick サンプルページ</title>

<link rel="stylesheet" href="./css/style.css">
<link rel="stylesheet" href="./css/slick.css">

<script src="./js/jquery-3.1.0.js"></script>
<script src="./js/slick.js"></script>
</head>

<body>

<div class="container">
  <h1>Slick サンプルページ</h1>

  <!-- ほぼ公式のサンプル通り、class名は自由につけます -->
  <div class="slides">
    <div><img src="./img/01.jpg" alt=""></div>
    <div><img src="./img/02.jpg" alt=""></div>
    <div><img src="./img/03.jpg" alt=""></div>
    <div><img src="./img/04.jpg" alt=""></div>
    <div><img src="./img/05.jpg" alt=""></div>
    <div><img src="./img/06.jpg" alt=""></div>
  </div><!-- /.slides -->
</div><!-- /.container -->

</body>
</html>


はい、
<div> タグに class="slides" というクラス名を付けてみました。が、この時のクラス名は何でも好きなように命名することが出来ます
貴方のこだわりを詰め込んだいい感じのクラス名にしてあげましょう。


もう一度ブラウザで読み込んでみて確認しましょう。
画像が縦に並んで表示されていますね。これはプラグインが働く前のプレーンな表示です。


5. プラグインの起動スクリプトを書く

いよいよ大詰めです。起動スクリプト を書きます。

起動スクリプトとは、プラグインを実際に動かすためのスクリプトです。
これまでのjQuery本体とプラグインの読み込みのための <script> タグの記述ではあくまでも読み込むだけでした。
起動スクリプトは読み込んだプラグインを動かすための記述です。

これについても公式サイトを参考にしましょう。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta charset="UTF-8">
<title>Slick サンプルページ</title>

<link rel="stylesheet" href="./css/style.css">
<link rel="stylesheet" href="./css/slick.css">

<script src="./js/jquery-3.1.0.js"></script>
<script src="./js/slick.js"></script>

<!-- これがいわゆる「起動スクリプト」です -->
<script>
jQuery(function($) {
  $('.slides').slick();
})
</script>

</head>

<body>

<div class="container">
  <h1>Slick サンプルページ</h1>

  <div class="slides">
    <div><img src="./img/01.jpg" alt=""></div>
    <div><img src="./img/02.jpg" alt=""></div>
    <div><img src="./img/03.jpg" alt=""></div>
    <div><img src="./img/04.jpg" alt=""></div>
    <div><img src="./img/05.jpg" alt=""></div>
    <div><img src="./img/06.jpg" alt=""></div>
  </div><!-- /.slides -->
</div><!-- /.container -->

</body>
</html>


起動スクリプトは必ずjQuery本体とプラグインとを読み込んだ後に記述しましょう。
「読み込んだ後に起動」これは鉄の掟です。


では、今度こそブラウザで読み込んで…、何か起きましたか?
先ほどまでただの縦並びになっている画像がちゃんとカルーセルの形にレイアウトされているはずです。
写真をめくるためのボタンも表示されるようになりましたね。

もっともベーシックな使い方ですが、以上がjQueryプラグインを動かすための一部始終です。


オプションを指定してカスタマイズする

設置したプラグインが微妙に思い通りの動作じゃないとき、イメージ通りにカスタマイズしたいですよね。

プラグインによって様々なオプションが用意されています。
このオプションを指定することで、jQueryプラグインを要望に合わせて細かくカスタマイズすることができます。

とりあえず Slick を読み込んで動かしてみましたが、ちょっと不満なことがあります。

  • ボタンを押さなければ次の画像が見れないので、一定時間で次の画像に切り替わるようにしたい
  • ボタンの表記が「Previous」「Next」となっているのを「前へ」「次へ」としたい

このような要望をオプションで解決してみましょう。


では指定することができるオプションを調べるにはどうすればいいでしょう?
はい、公式サイトですね。Settingsというセクションに指定可能なオプションが解説されているみたいです。
実にありがたい。


f:id:todays_mitsui:20160826230324p:plain

オプションの指定は起動スクリプトの中で行います。

先ほどまでの起動スクリプトをもとに、

<script>
jQuery(function($) {
  $('.slides').slick();
})
</script>

書き替えます。
.slick の後の括弧() がオプションのためのスペースです。

<script>
jQuery(function($) {
  $('.slides').slick(
    { autoplay: true }
  );
})
</script>

{ autoplay: true } という記述を足しました。
これでボタンを押さなくても画像がめくられるようになったはずです。

続いて行きましょう。
ボタンの表記を変えるには prevArrownextArrow というオプション項目があるみたいですよ。
デフォルト値が <button type="button" class="slick-prev">Previous</button> だと書いてるので、これをコピって部分的に書き替える感じでやりましょう。

<script>
jQuery(function($) {
  $('.slides').slick(
    { autoplay: true, prevArrow: '<button type="button" class="slick-prev">前へ</button>', nextArrow: '<button type="button" class="slick-next">次へ</button>' }
  );
})
</script>

はい。

できました…。


と言いつつ、これではあまりにも見づらいのでスペースや改行を入れ込んで整えます。

<script>
jQuery(function($) {
  $('.slides').slick({
    autoplay: true,
    prevArrow: '<button type="button" class="slick-prev">前へ</button>',
    nextArrow: '<button type="button" class="slick-next">次へ</button>',
  });
})
</script>

JavaScriptのルールでは見やすさを整えるためのスペースや改行は(一部例外はあるものの)自由に入れていいことになっています。
オプションが増えてくると適当に改行を入れておいかないと見通しが悪くなります。

あとで読んだとき訳が分からなくなって困るのは自分です。
起動スクリプトを美しく書くことにもこだわってみましょう。


少々話がそれました。
では、オプションを指定したバージョンのカルーセルをご覧ください。

いい感じですね。


jQueryプラグインを使うときの注意点

さて、基本的な使い方は以上。次は基本的な注意点です。

  1. jQuery本体は一番最初に一度だけ読み込む
  2. jQuery本体とプラグインはなるべく最新バージョンを使う
  3. jQuery本体やプラグインを書き換えようとしない


1. jQuery本体は一番最初に一度だけ読み込む

jQueryの本体は必ず一番最初に読み込みましょう。 そして、ページ内で複数のプラグインを使う場合でも1度だけ読み込めば大丈夫だと覚えましょう。


ちなみに、jQuery本体を2個3個読み込んだらどうなるか知りたいですか?
私の経験では2個目のjQuery本体を読み込んだ瞬間にそれまでに読み込んだプラグインがすべてリセットされて、まぁ厄介なことになります。

jQuery本体を複数読み込むメリットはありません。


2. jQuery本体とプラグインはなるべく最新バージョンを使う

悪いことは言わないので最新を使いましょう。
発見されたバグが修正されている、便利な機能が追加されているなど、新しいバージョンを使うメリットがきっとあります。

プラグインによってはjQuery本体の最低バージョンを明記しているものもあります。
参考までに Slick の公式サイトには、

requires jQuery 1.7 +

と書いてあります。
これは「jQuery バージョン1.7以上じゃないと動作を保証しないよ」という意味ですね。


逆にjQuery本体を最新にしたらプラグインが動かなくなった場合はどうしましょうか?

はっきり言います。
jQuery本体のバージョンアップに追いついていないようなメンテナンスの行き届いていないプラグインを使い続けるのは危険です。
ほかのプラグインへの乗り換えを検討する絶好のチャンスですよ。


3. jQuery本体やプラグインを書き換えようとしない

jQuery本体もプラグインも所詮はただの JS ファイルなのでエディタで開いて書き換えることができます。
ですが、プラグインの動作が微妙に望み通りでないときでもjQuery本体やプラグインを書き換えようとしないでください。壊れます。


jQueryプラグインの中身を書き換えなくても動作をカスタマイズできるように、プラグインにオプションを指定できる仕組みが備わっています。
まずは希望する動作を実現するようなオプションが用意されているかどうか調べましょう。

どうやって調べるか。もちろんプラグインの公式サイトを見るわけです。
プラグインの作者が想定している範囲で想定している使い方をするのが、トラブルを起こさないために重要です。


まとめ

jQueryプラグインの大まかな使い方と、基本的な注意点を解説してきました。
もう一度書き並べてみましょう。

大まかな流れ

  1. jQuery本体を読み込む
  2. jQueryプラグインを読み込む
  3. (プラグインに付属のCSSがあれば、)CSSを読み込む
  4. プラグインを適用する HTML を書く
  5. プラグインの起動スクリプトを書く

基本的な注意点

  1. jQuery本体は一番最初に一度だけ読み込む
  2. jQuery本体とプラグインはなるべく最新バージョンを使う
  3. jQuery本体やプラグインを書き換えようとしない


これらはjQueryプラグインを使う上で毎回くりかえす工程です。
基本の部分だからこそ、コピペでなんとなくではなく基礎を押さえてコーディングしていきましょう。


もっと使いこなすために

jQueryは JavaScript を理解していなくても使えてしまうのが良いところでもあり、悪いところでもありますね。
jQueryとjQueryプラグインとをもっと使いこなすために、合わせて学ぶといいことを紹介して終わりたいと思います。

  • JavaScript の基本文法を覚える
    jQuery以前の部分で躓かないために。MDNのチュートリアルがおすすめです

  • プラグインのデフォルトを知ってみる
    オプションが指定できるということは、オプションを指定しないときのデフォルトの値があるはずです
    調べてみましょう

  • 英語を読もう
    jQueryに限らず、情報源は英語で書かれたものが大半です。英語は苦手?大丈夫、コードだけ拾い読みすればいいんですよ


そんなわけでjQueryプラグインそのものの使い方を解説してみました。
こういうのってありそうで無かったですよね。

この調子でパート4まで続きます。


私からは以上です(続く)


【jQueryの基本の"き"】シリーズ

blog.mudatobunka.org

blog.mudatobunka.org

blog.mudatobunka.org

React で this.props.children に新しい Props を渡す

f:id:todays_mitsui:20160814183151p:plain

React でカスタムコンポーネントを作るとき、コンポーネントの子要素には this.props.children でアクセスできます。
この this.props.children はそのままレンダリングすることもできるのですが、何かしらの Props を渡したくなったらどうするのでしょうか。

ざっくり調べた感じ Stack Overflow とか海外のブログにしか情報が無いようだったのでまとめてみます。


TL;DR

いきなり結論から、
this.props.children に直接 Props を渡すことはできません。
代わりの方法として、React.cloneElement() で React要素をクローンする時に Props を渡すことができるので、this.props.children をクローンしつつ Props を渡せばいいようです。

デモを用意しました。


以下のようにすればローカルでデモをいじりつつ試せます。

$ git clone https://github.com/todays-mitsui/passing-props-to-children-sample.git
$ cd passing-props-to-children-sample
$ npm install
$ npm start


要素に Props を渡す

this.props.children に限らず React要素は React.cloneElement() という API でクローンできます。
そのとき第2引数にオブジェクトを渡すと、React要素が持っている既存の Props とマージされた後、新しい Props として設定されるとのことです。

let elementWithProps = React.cloneElement(element, { foo: 'bar' })

公式ドキュメントに解説があるので、詳しくはそちらをどうぞ。


this.props.children に応じた処理をする

ところで this.props.children は状況によって様々な型の値になります。
複数の子要素を持っている場合には this.props.childrenReact要素の配列 になります。
その他、子要素がただのテキストノードだった場合には string に、子要素を持たない場合は undefined と、まぁ場合によっていろいろみたいです。

そんな this.props.children を上手く扱うために React.Children というユーティリティクラスが用意されています。
使うときには React.Children で参照するほかに、ES2015 で記述しているなら、

import { Children } from 'react'

というように個別にインポートしてもいいでしょう。


今回は React.Children.map() を使って子要素一つひとつに Props を渡します。

const newProps = { foo: 'bar' }

const childrenWithProps = React.Children.map(
  this.props.children,
  (child) => {
    // 各子要素をクローンしつつ newProps を渡す
    return React.cloneElement(child, newProps)
  }
)

さて、実はこれだけではいけません。
子要素がテキストノードを含んでいる場合には、上記の child に string が渡されます。そして React.cloneElement() は string を受け取ってくれないので、そこでエラーが発生します。

なので child の type を判別しつ上手いこと処理を分岐しましょう。
string が渡ってきた場合には何もせず、そのまま返すようにします。

const newProps = { foo: 'bar' }

const childrenWithProps = React.Children.map(
  this.props.children,
  (child) => {
    console.info(typeof child, child)

    switch (typeof child) {
      case 'string':
        // 子要素がテキストノードだった場合はそのまま return
        return child

      case 'object':
        // React要素だった場合は newProps を渡す
        return React.cloneElement(child, newProps)

      default:
        // それ以外の場合はとりあえず null 返しとく
        return null
    }
  }
)

これで this.props.children を複製しつつ Props を渡した childrenWithProps を作ることができました。


React.Children.map() についても公式ドキュメントの解説が親切でした。


簡単なデモ

やり方の説明としては以上なんですが、上記のコードは単体では動かないので実際に動作する簡単なデモを書きました。

ロジック部分は1ファイルでこのようになっています。

/* main.js */

import React, { Children } from 'react'
import ReactDom from 'react-dom'


class Child extends React.Component {
  render() {
    const parentName = this.props.parentName || 'UnknownParent'
    const name = this.props.name || 'UnknownChild'

    return (
      <p>
        ParentName: <em>{parentName}</em> > ChildName: <em>{name}</em>
      </p>
    )
  }
}

class Parent extends React.Component {
  render() {
    const newProps = { parentName: 'foo' }

    const childrenWithProps = Children.map(
      this.props.children,
      (child) => {
        console.info(typeof child, child)

        switch (typeof child) {
          case 'string':
            return child

          case 'object':
            return React.cloneElement(child, newProps)

          default:
            return null
        }
      }
    )

    return (
      <div>
        {childrenWithProps}
      </div>
    )
  }
}


ReactDom.render(
  (
    <Parent>
      ### Text Node ###
      <Child name='hoge' />
      <Child name='fuga' />
      <Child name='piyo' />
    </Parent>
  ),
  document.querySelector('.container')
)

<Child> コンポーネントは name, parentName という2つの Props を <p> タグの中で表示するだけの簡単なものです。
今回は parentName の方を親要素の <Parent> コンポーネントから渡してあげています。


今回のデモのソースは全て GitHub に置いてあります。


まとめ

React はもともと API が少なくて学習コストが少ないと思っているんですが、少ないなりに覚えておくと便利な API もありますね。
React.cloneElement()this.props.children をカスタマイズする以外にもいろいろな用途で使えるはずです。


私からは以上です。