20211008のJavaScriptに関する記事は10件です。

【HTML】戻るボタンの実装方法

はじめに 戻るボタンを実装する機会はかなり多いと思うのですが、そのときのための備忘録として残しておきます。 戻るボタンの実装 aタグでの実装 HTML <a href="javascript:history.back();">戻る</a> buttonタグでの実装 HTML <button type="button" onclick="history.back()">戻る</button> type="button"をちゃんと記述しないと、デフォルトでtype=submitとなってしまうので要注意!! formタグでの実装 HTML <form> <input type="button" onclick="history.back()" value="戻る"> </form> おわりに すべてHTML内の実装したい箇所に記述すれば良いので簡単ですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

array.find()の便利技その1

棚に以下が置いてあります。 const stack = [ {name:"たまねぎ", date:true}, {name:"葡萄", date:false}, {name:"たまねぎ", date:false}, {name:"林檎", date:false}, ]; 今日はカレーを作りたいので「たまねぎ」が欲しいです。 以下のように欲しい食材を定義しました。 const target = {name:"たまねぎ"}; では、findを用いて「たまねぎ」を棚から取りましょう。注意点としてdate(消費期限)が切れる前の「たまねぎ」だけを棚から取りましょう。 ※trueは賞味期限が切れていません。 答え const TAMANEGI = stack.find((food)=>{ if(!food.date){ return false } return food.name === target.name; }) さらにレベルアップ 条件に合う「たまねぎ」がない場合は「undifinde」が返りますが、そんなもの食べられないので、食べ物を返しましょう。以下のコードの一部を書き換えconsole.logで「いただきます!」を出力してください。 const stack = [ { name: "たまねぎ", date: true }, { name: "葡萄", date: false }, { name: "たまねぎ", date: false }, { name: "林檎", date: false } ]; const target = { name: "たまねぎマン" }; const TAMANEGI = stack.find((food) => { if (!food.date) { return false; } return food.name === target.name; }); if ("らーめん" === TAMANEGI.name) { console.log("いただきます!"); } 答え const stack = [ { name: "たまねぎ", date: true }, { name: "葡萄", date: false }, { name: "たまねぎ", date: false }, { name: "林檎", date: false } ]; const target = { name: "たまねぎマン" }; const TAMANEGI = stack.find((food) => { if (!food.date) { return false; } return food.name === target.name; }) ?? { name: "らーめん" }; if ("らーめん" === TAMANEGI.name) { console.log("いただきます!"); } null合体演算子最強!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScriptと黒魔術で演算子オーバーロード(もどき)を実現

序論 演算子オーバーロードとは  まず、オブジェクト指向の三大要素の一つに多態性というものがある。演算子に独自の動作をさせるのが演算子オーバーロードだ。  例えば、2つの配列から内積を求める処理を書くとしよう。 const a = [1, 2, 3], b = [4, 5, 6]; console.log(a * b); // 内積の32を出力できればいいなぁ~  このように、演算子の動作を通常の挙動から変えることを、演算子オーバーロードと言う。計算式が見やすく表現できるメリットがある。  C++言語にはこれを簡単に実装できる機能がある。しかし、JavaScriptには存在しない。それをどうにかしてJavaScriptで表現できるようにするのが本稿の目的である。  確かに、演算子に拘らず、専用の関数を作ってしまえばそれまでだ。しかし、我々はロマンと言うものを忘れてはならない。 先行研究の紹介  私が本稿を執筆するに至って、参考にしたものがある。こちらの記事の最後にあるコードを解説する。 getter  まず、式を評価する直前に、initCompose()が実行される。なぜ、このタイミングで実行できるのか。それはcomposeがwindowオブジェクトのgetterになっているからだ。最後に関数を返しているが、このgetterが返す値がそれになる。 prototype  次に、Function.prototype.valueOfを書き換えている。Function.prototypeとは、関数オブジェクトの基底クラスである。これを書き換えると、全てのインスタンス(ここでは関数)に適用される。 valueOf  valueOfは、式として評価された際に実行されるプロパティだ。1を返しているが、値に特に意味はない。ここでのthisは評価されたオペランドだ。valueOfを書き換えることで、オペランドを回収している。 まとめ  関数を式として評価された際、それぞれのオペランドを回収している。そして、getterが返した関数がそれらのオペランドを使うことで、まるで演算子オーバーロードのような処理を実現しているのだ。  この方法は非常に素晴らしい。ただし、一つ問題がある。どんな演算子を使っても結果が同じなのだ。そこで、私はこのコードを改変し、演算子の種類によって異なるオーバーロードができるようなプログラムを作成した。それは本論で述べる。 余談  ここで紹介した、prototypeとvalueOfの書き換えは、JavaScriptでは黒魔術と呼ばれ、忌み嫌われている。prototypeの書き換えは、windowオブジェクトのプロパティを書き換えるグローバル汚染と同じく、スコープを越えて極めて大きな影響力を持つ。valueOfの書き換えは、暗黙的な型変換そのものだ。どちらも、思いもよらぬバグを引き起こす可能性を秘めている。ただ、悪魔に魂を売ると強大な力を得られるように、これらを使いこなせば豊かな表現ができるようになる。 本論  先に成果物を掲載し、次に内容の解説に入る。 成果物  こちらのコードを見ていただきたい。mjsとして呼び出せるようにしておいた。 使い方 const {over} = await import('https://rpgen3.github.io/overload/mjs/overload.mjs'); // 演算子オーバーロードの登録 over.load = [Array, '*', Array, (a, b) => a.map((v, i) => v * b[i]).reduce((p, x) => p + x)]; // 内積 // 実際に使う console.log('内積', over.load([1,2,3] * [4,5,6])); over.load = [Array, '*', Number, (a, b) => a.map(v => v * b)]; over.load = [Number, '*', Array, (a, b) => b.map(v => v * a)]; console.log('ベクトルのスカラー倍1', over.load([1,2,3] * Object(4))); console.log('ベクトルのスカラー倍2', over.load(Object(3) * [4,5,6]));  確かに、演算子のオーバーロードができているようだ。 注意点 プリミティブな値の扱い プリミティブな値はObject()か、そのコンストラクタでの変換が必要 使用できる演算子の制限 JavaScriptで定義されている二項演算子のみ使用可能 // Number型の場合 Object(1234); // または、 new Number(1234); 解説 演算子の判定方法  先行研究のコードでは、演算子によって処理を変えることまではできていなかった。それは、演算結果を破棄しているからだ。実は、演算結果はgetterの返す関数の引数から受け取ることができる。演算結果からどう演算子を推定するか?そこで私はあるアイデアを思い付いた。先行研究のコードで、return 1;と雑に返していた箇所がある。他の定数を返せば、演算結果が変わるはずだ。また、2つの定数を演算した結果が他の演算子と被らなければ良いということだ。そこで、JavaScriptで使える二項演算子を同時に検証するアプリを作った。  最も注意すべき演算子は累乗だ。指数が大きくなると計算できない可能性がある。だから、右のオペランドを極力小さい整数にし、順番に検証していった。すると、21と3のペアが奇跡的にすべての演算子が被らない値になることが分かった。他のもっと良いペアが存在するかもしれないが、ひとまずこれを採用した。 const magicNumber = [21, 3];  かくして、overload.mjsの1行目がこう記述されることになった。変数名がmagicNumberだなんて、清々しいまでの開き直りようである。 演算子オーバーロードの関数の管理  キーに関数を設定できるMapオブジェクトを使用した。Mapオブジェクトは合計で3つ使う。まず、左オペランドのコンストラクタをキーに、Mapオブジェクトを呼び出す。それに対して、文字列に型変換した演算結果をキーに、Mapオブジェクトを呼び出す。さらに、それに対して、右オペランドのコンストラクタをキーに、演算子オーバーロードとして設定された関数を呼び出す流れだ。 演算結果が数値以外になる二項演算子の場合  演算結果を文字列型に変換しているのは、このような演算子も少しだけ対応するためだ。例えば、比較演算子がある。マジックナンバーは、21と3であるので、>ならtrueが返り、<ならfalse、==ならfalseだ。同じ演算結果ならどうなるだろう?先行研究のコードと同様に、同じ演算結果になる二項演算子同士の演算子オーバーロードは区別できない、何を使っても同じ結果となる。そのため、より後にオーバーロードされた関数が優先されるだろう。 結論  JavaScriptで演算子オーバーロードを実装することができた。式の評価直後に元に戻すとは言え、prototypeを書き換えており、実用は難しいだろう。しかし、JavaScriptでも演算子オーバーロードができるぞとネタにできる点においては、大いに意味があると思われる。   謝辞  本稿の黒魔術的な部分は@alucky0707さんの記事に依るところが大きいです。特にprototypeを書き換える発想、これが最も本稿の演算子オーバーロードを支える要素です。この場を借りて深く御礼申し上げます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScriptと黒魔術で演算子オーバーロードを実装してみた

序論 演算子オーバーロードとは  まず、オブジェクト指向の三大要素の一つに多態性というものがある。演算子に独自の動作をさせるのが演算子オーバーロードだ。  例えば、2つの配列から内積を求める処理を書くとしよう。 const a = [1, 2, 3], b = [4, 5, 6]; console.log(a * b); // 内積の32を出力できればいいなぁ~  このように、演算子の動作を通常の挙動から変えることを、演算子オーバーロードと言う。計算式が見やすく表現できるメリットがある。  C++言語にはこれを簡単に実装できる機能がある。しかし、JavaScriptには存在しない。それをどうにかしてJavaScriptで表現できるようにするのが本稿の目的である。  確かに、演算子に拘らず、専用の関数を作ってしまえばそれまでだ。しかし、我々はロマンと言うものを忘れてはならない。 先行研究の紹介  私が本稿を執筆するに至って、参考にしたものがある。こちらの記事の最後にあるコードを解説する。 getter  まず、式を評価する直前に、initCompose()が実行される。なぜ、このタイミングで実行できるのか。それはcomposeがwindowオブジェクトのgetterになっているからだ。最後に関数を返しているが、このgetterが返す値がそれになる。 prototype  次に、Function.prototype.valueOfを書き換えている。Function.prototypeとは、関数オブジェクトの基底クラスである。これを書き換えると、全てのインスタンス(ここでは関数)に適用される。 valueOf  valueOfは、式として評価された際に実行されるプロパティだ。1を返しているが、値に特に意味はない。ここでのthisは評価されたオペランドだ。valueOfを書き換えることで、オペランドを回収している。 まとめ  関数を式として評価された際、それぞれのオペランドを回収している。そして、getterが返した関数がそれらのオペランドを使うことで、まるで演算子オーバーロードのような処理を実現しているのだ。  この方法は非常に素晴らしい。ただし、一つ問題がある。どんな演算子を使っても結果が同じなのだ。そこで、私はこのコードを改変し、演算子の種類によって異なるオーバーロードができるようなプログラムを作成した。それは本論で述べる。 余談  ここで紹介した、prototypeとvalueOfの書き換えは、JavaScriptでは黒魔術と呼ばれ、忌み嫌われている。prototypeの書き換えは、windowオブジェクトのプロパティを書き換えるグローバル汚染と同じく、スコープを越えて極めて大きな影響力を持つ。valueOfの書き換えは、暗黙的な型変換そのものだ。どちらも、思いもよらぬバグを引き起こす可能性を秘めている。ただ、悪魔に魂を売れば強大な力を得られるように、これらを使いこなせば豊かな表現ができるようになる。 本論  先に成果物を掲載し、次に内容の解説に入る。 成果物  こちらのコードを見ていただきたい。mjsとして呼び出せるようにしておいた。 使い方 const {over} = await import('https://rpgen3.github.io/overload/mjs/overload.mjs'); // 演算子オーバーロードの登録 over.load = [Array, '*', Array, (a, b) => a.map((v, i) => v * b[i]).reduce((p, x) => p + x)]; // 内積 // 実際に使う console.log('内積', over.load([1,2,3] * [4,5,6])); over.load = [Array, '*', Number, (a, b) => a.map(v => v * b)]; over.load = [Number, '*', Array, (a, b) => b.map(v => v * a)]; console.log('ベクトルのスカラー倍1', over.load([1,2,3] * Object(4))); console.log('ベクトルのスカラー倍2', over.load(Object(3) * [4,5,6]));  確かに、演算子のオーバーロードができているようだ。 注意点 プリミティブな値の扱い プリミティブな値はObject()か、そのコンストラクタでの変換が必要 // Number型の場合 Object(1234); // または、 new Number(1234); 使用できる演算子の制限 JavaScriptで定義されている二項演算子のみ使用可能 解説 演算子の判定方法  先行研究のコードでは、演算子によって処理を変えることまではできていなかった。それは、演算結果を破棄しているからだ。実は、演算結果はgetterの返す関数の引数から受け取ることができる。演算結果からどう演算子を推定するか?そこで私はあるアイデアを思い付いた。先行研究のコードで、return 1;と雑に返していた箇所がある。他の定数を返せば、演算結果が変わるはずだ。また、2つの定数を演算した結果が他の演算子と被らなければ良いということだ。そこで、JavaScriptで使える二項演算子を同時に検証するアプリを作った。  最も注意すべき演算子は累乗だ。指数が大きくなると計算できない可能性がある。だから、右のオペランドを極力小さい整数にし、順番に検証していった。すると、21と3のペアが奇跡的にすべての演算子が被らない値になることが分かった。他のもっと良いペアが存在するかもしれないが、ひとまずこれを採用した。 const magicNumber = [21, 3];  かくして、overload.mjsの1行目がこう記述されることになった。変数名がmagicNumberだなんて、清々しいまでの開き直りようである。 演算子オーバーロードの関数の管理  キーに関数を設定できるMapオブジェクトを使用した。Mapオブジェクトは合計で3つ使う。まず、左オペランドのコンストラクタをキーに、Mapオブジェクトを呼び出す。それに対して、演算結果をキーに、Mapオブジェクトを呼び出す。さらに、それに対して、右オペランドのコンストラクタをキーに、演算子オーバーロードとして設定された関数を呼び出す流れだ。 演算結果が数値以外になる二項演算子の場合  演算結果を文字列型に変換しているのは、次のような演算子に少しだけ対応するためだ。例えば、比較演算子がある。マジックナンバーは、21と3であるので、>ならtrueが返り、<ならfalse、==ならfalseだ。同じ演算結果ならどうなるだろう?先行研究のコードと同様に、同じ演算結果になる二項演算子同士の演算子オーバーロードは区別できない、何を使っても同じ結果となる。そのため、より後にオーバーロードされた関数が優先されるだろう。 結論  JavaScriptで演算子オーバーロードを実装することができた。式の評価直後に元に戻すとは言え、prototypeを書き換えており、実用は難しいだろう。しかし、JavaScriptでも演算子オーバーロードができるぞとネタにできる点においては、大いに意味があると思われる。   謝辞  本稿の黒魔術的な部分は@alucky0707さんの記事に依るところが大きいです。特にprototypeを書き換える発想、これが最も本稿の演算子オーバーロードを支える要素です。この場を借りて深く御礼申し上げます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Multiple Select】特定のトリガーでプルダウンをリセットする方法

やりたいこと あるボタンのクリックイベントで、Multiple Selectの選択状況をリセットしたい。 Multiple Selectとは、チェックボックスで複数選択できるプルダウンなどを作れるjQueryプラグイン。 公式はこちら Multiple Selectの特徴 Multiple Selectは通常のselect要素で作るプルダウンとは少し異なるため、valueの取得の仕方などの勝手が変わってきます。 そのかわり、Multiple Selectの公式で用意されているさまざまなオプションやメソッドを使うことができます。 今回は「プルダウンのリセット」が目的なので、uncheckAllメソッドを使用していきます。uncheckAllは「すべてのチェックを外す」メソッドになります。 uncheckAllでリセット <button id='reset'>リセット</button> <select id='multiple-select'> <option value='1'>りんご</option> <option value='2'>バナナ</option> <option value='3'>ぶどう</option> </select> $(function () { $('#reset').click(function () { const $select = $('#multiple-select') $select.multipleSelect('uncheckAll') }) }) まとめ 他にもさまざまなメソッドが用意されており、上記とは逆にすべて選択状態にするメソッドなんかもありますので、Multiple Selectを使っている方はぜひ試してみてください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

react-burger-menuとはなんなのか

はじめに Next.jsの開発でバーガーメニュー作りたいなと思って調べたら react-burger-menuというもので簡単にバーガーメニューが作れるようなので紹介します。 使い方 一応公式のREADME置いときます。 https://github.com/negomi/react-burger-menu 1. インストール(Installation) 以下のコマンドでインストールを行う npm install react-burger-menu --save or yarn add react-burger-menu TypeScriptを使っている方は以下のコマンドでインストール npm install @types/react-burger-menu --save or yarn add @types/react-burger-menu 2. 利用方法(Usage) アニメーション(animation)について react-burger-menuでは以下のようなアニメーションを選択できます。 ・slide ・stack ・elastic ・bubble ・push ・pushRotate ・scaleDown ・scaleRotate ・fallDown ・reveal 実際のアニメーションは公式が出しているサイトで見れます。 (https://negomi.github.io/react-burger-menu/) 使用する際は, ファイル内で以下のようにimportします。 import { slide as Menu } from 'react-burger-menu' この時, slide以外のアニメーションを使いたい場合は上で記述したアニメーションに適宜書き換えれば変更することができます。 プロパティ(Properties)について Page wrapper ページの残りをラップする要素は以下のようにMenuコンポーネントの後に配置し, idを一致させる。 <Menu pageWrapId={ "page-wrap" } /> <main id="page-wrap"> ・ ・ ・ </main> Outer container 全てのコンテンツをラップする親要素がある場合は, 親要素のidをouterContainerIdと以下のように一致させる。 <div id="outer-container"> <Menu pageWrapId={ "page-wrap" } outerContainerId={ "outer-container" } /> <main id="page-wrap"> ・ ・ ・ </main> </div> アニメーションの種類によってこれらのプロパティを指定しなければならない場合があるので, それらを以下の表で示しました。 slide, stack, bubble以外は基本的に指定する感じです。 Animation pageWrapId outerContainerId slide stack elastic ✔︎ ✔︎ bubble push ✔︎ ✔︎ pushRotate ✔︎ ✔︎ scaleDown ✔︎ ✔︎ scaleRotate ✔︎ ✔︎ fallDown ✔︎ ✔︎ reveal ✔︎ ✔︎ Position バーガーメニューアイコンの位置を指定できます。 デフォルトではアイコンは左に配置されるようになっていますが, 、右側に配置したい場合は以下のように指定できます。 <Menu right /> Width メニューの幅を以下のように指定できます。デフォルトは 300 です。 <Menu width={ 280 } /> <Menu width={ "280px" } /> <Menu width={ "20%" } /> Open state メニューの開閉の状態をisOpenで制御します。 デフォルトはfalseです。 Open menu handler ボタンなどを押してメニューを開く関数を渡すときに使用します。 <Menu onOpen={ handleOnOpen } /> Close menu handler ボタンやオーバーレイ(overlay)の部分などを押したときにメニューを閉じる関数を渡す時に使用します。 <Menu onClose={ handleOnClose } /> onOpenとonCloseはプロパティとして含めなくてもデフォルトで最低限の動作はしてくれます。 しかし, onOpenやonCloseを使うときは, 渡す関数内で必ず自身でメニューの開閉を処理するようにしなければなりません。 State change onStateChangeはコールバック関数を受け取り, メニューが開いているか閉じているかを検出することができます。onStateChangeに渡すコールバック関数の引数は, 最新の状態を保持するオブジェクトとなります。 let isMenuOpen = (state) => { return state.isOpen; }; <Menu onStateChange={ isMenuOpen } /> Close on Escape disableCloseOnEscプロパティを使用することで, Escキーを押した時にメニューが閉じる動作を無効にすることができます。これにより, レスポンシブメニューなどでメニューを常時開いておきたい場合などに便利です。 <Menu disableCloseOnEsc /> Custom keydown handler customOnKeyDownプロパティは, キーを押した際のメニューの状態を細かく制御することができます。例としては, 以下のようにMenuコンポーネントのインスタンスを複数使用している場合にEscキーを一度押すだけで全てのインスタンスを閉じる(メニューを全て閉じる)機能を実装する際に役立ちます。 const [areMenusOpen, setAreMenusOpen] = useState(false); const closeAllMenusOnEsc = (event) => { event = event || window.event; if (event.key === 'Escape' || event.keycode === 27) { setAreMenusOpen(false); } }; <MenuFirst customOnKeyDown={closeAllMenusOnEsc} isOpen={areMenusOpen} /> <MenuSecond customOnKeyDown={closeAllMenusOnEsc} isOpen={areMenusOpen} /> ※このプロパティを使用するとデフォルトのEscキーでメニューを閉じる機能が無効になるため, 例えばshiftキーを押したときにメニューを閉じる機能を実装した場合, Escキーは機能を失います。Escキーを使用したい場合は, 自身で関数内に処理を追加で記述する必要があります。 Overlay noOverlayプロパティを使用することで, デフォルトのオーバーレイ(overlay)をオフにすることができます。 <Menu noOverlay /> また, disableOverlayClickを使用することでオーバーレイ(overlay)を押した際のイベント(メニューが閉じるなど)を無効にすることができます。プロパティはブール値である必要があります。 <Menu disableOverlayClick /> <Menu disableOverlayClick={ () => shouldDisableOverlayClick() } /> Transitions noTransitionプロパティを使用することで, 全てのトランジションやアニメーションを無効にすることができます。 <Menu noTransition /> Custom icons customBurgerIcon, customCrossIconプロパティを使用することでデフォルトのバーガーアイコンとクロスアイコンを独自に置き換えることができます。 <Menu customBurgerIcon={ <img src="img/icon.svg" > } /> <Menu customCrossIcon={ <img src="img/cross-icon.svg" > } /> また, 各プロパティにfalseを渡すことでアイコン要素を無効にすることもできます。その場合は, ボタンなどを独自に作成してisOpenプロパティでメニューの開閉を制御します。 Custom ID and/or classNames MenuコンポーネントのプロパティとしてidとclassNameを指定することができます。 <Menu id={ "side-bar" } className={ "my-menu" } /> また, メニュー全体の各要素に対してプロパティとしてclassNameを指定することができます。(以下のclassNameは適当に考えたものです) <Menu burgerButtonClassName={ "burger-button" } burgerBarClassName={ "burger-bars" } crossButtonClassName={ "cross-button" } crossClassName={ "burger-cross" } menuClassName={ "burger-menu" } morphShapeClassName={ "burger-morph-shape" } itemListClassName={ "burger-item-list" } overlayClassName={ "burger-overlay" } /> また, html, body要素に対してclassNameを指定することもできます。 <Menu htmlClassName={ "html" } /> <Menu bodyClassName={ "body" } /> Focusing the first menu item デフォルトではメニューを開いた際にリストの最初の項目がフォーカスされた状態となっているため, disableAutoFocusプロパティを使用することで無効にすることができます。 <Menu disableAutoFocus /> Custom item list element メニューのリストは, nav要素にラップされており, ナビゲーションを使用しない場合はitemListElementプロパティでdivを指定します。 <Menu itemListElement /> Styling Menuコンポーネントは内部的にスタイルやアニメーションなどの処理を行います。 以下はバーガーメニューのスタイリングの例です。 CSS Menuコンポーネントは以下のクラスを持ちます。 /* バーガーボタンの位置とサイズ */ .bm-burger-button { position: fixed; width: 36px; height: 30px; left: 36px; top: 36px; } /* バーガボタンのバーのスタイル */ .bm-burger-bars { background: #373a47; } /* バーガーボタンのホバー */ .bm-burger-bars-hover { background: #a90000; } /* クロスボタンの位置とサイズ */ .bm-cross-button { height: 24px; width: 24px; } /* クロスボタンのカラー・形状 */ .bm-cross { background: #bdc3c7; } /* サイドバーのラッパースタイル - アニメーションが壊れる可能性があるため触るときは注意 */ .bm-menu-wrap { position: fixed; height: 100%; } /* サイドバーのスタイル */ .bm-menu { background: #373a47; padding: 2.5em 1.5em 0; font-size: 1.15em; } /* bubbleやelasticで必要なモーフの形状 */ .bm-morph-shape { fill: #373a47; } /* メニューリストのラッパースタイル*/ .bm-item-list { color: #b8b7ad; padding: 0.8em; } /* 個々のリストのスタイル */ .bm-item { display: inline-block; } /* オーバーレイ(overlay)のスタイリング */ .bm-overlay { background: rgba(0, 0, 0, 0.3); } CSS in JS Menuコンポーネントに以下のstylesオブジェクトを渡すことでスタイリングができます。 const styles = { bmBurgerButton: { position: 'fixed', width: '36px', height: '30px', left: '36px', top: '36px' }, bmBurgerBars: { background: '#373a47' }, bmBurgerBarsHover: { background: '#a90000' }, bmCrossButton: { height: '24px', width: '24px' }, bmCross: { background: '#bdc3c7' }, bmMenuWrap: { position: 'fixed', height: '100%' }, bmMenu: { background: '#373a47', padding: '2.5em 1.5em 0', fontSize: '1.15em' }, bmMorphShape: { fill: '#373a47' }, bmItemList: { color: '#b8b7ad', padding: '0.8em' }, bmItem: { display: 'inline-block' }, bmOverlay: { background: 'rgba(0, 0, 0, 0.3)' } } <Menu styles={ styles } /> 最後に なんかほぼ公式を和訳してちょっと脚色した感じなので, もし間違いなどあれば教えてい頂けますと幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

react-burger-menu is 何

はじめに react-burger-menu は簡単にバーガーメニューを作成できるReactのライブラリらしいです。 Next.jsの開発でバーガーメニュー作りたいなと思って調べたら出てきて使って見たらよかったので紹介します。 使い方 一応公式のREADME置いときます。 https://github.com/negomi/react-burger-menu 1. インストール(Installation) 以下のコマンドでインストールを行う npm install react-burger-menu --save or yarn add react-burger-menu TypeScriptを使っている方は以下のコマンドでインストール npm install @types/react-burger-menu --save or yarn add @types/react-burger-menu 2. 利用方法(Usage) アニメーション(animation)について react-burger-menuでは以下のようなアニメーションを選択できます。 ・slide ・stack ・elastic ・bubble ・push ・pushRotate ・scaleDown ・scaleRotate ・fallDown ・reveal 実際のアニメーションは公式が出しているサイトで見れます。 (https://negomi.github.io/react-burger-menu/) 使用する際は, ファイル内で以下のようにimportします。 import { slide as Menu } from 'react-burger-menu' この時, slide以外のアニメーションを使いたい場合は上で記述したアニメーションに適宜書き換えれば変更することができます。 プロパティ(Properties)について Page wrapper ページの残りをラップする要素は以下のようにMenuコンポーネントの後に配置し, idを一致させる。 <Menu pageWrapId={ "page-wrap" } /> <main id="page-wrap"> ・ ・ ・ </main> Outer container 全てのコンテンツをラップする親要素がある場合は, 親要素のidをouterContainerIdと以下のように一致させる。 <div id="outer-container"> <Menu pageWrapId={ "page-wrap" } outerContainerId={ "outer-container" } /> <main id="page-wrap"> ・ ・ ・ </main> </div> アニメーションの種類によってこれらのプロパティを指定しなければならない場合があるので, それらを以下の表で示しました。 slide, stack, bubble以外は基本的に指定する感じです。 Animation pageWrapId outerContainerId slide stack elastic ✔︎ ✔︎ bubble push ✔︎ ✔︎ pushRotate ✔︎ ✔︎ scaleDown ✔︎ ✔︎ scaleRotate ✔︎ ✔︎ fallDown ✔︎ ✔︎ reveal ✔︎ ✔︎ Position バーガーメニューアイコンの位置を指定できます。 デフォルトではアイコンは左に配置されるようになっていますが, 、右側に配置したい場合は以下のように指定できます。 <Menu right /> Width メニューの幅を以下のように指定できます。デフォルトは 300 です。 <Menu width={ 280 } /> <Menu width={ "280px" } /> <Menu width={ "20%" } /> Open state メニューの開閉の状態をisOpenで制御します。 デフォルトはfalseです。 Open menu handler ボタンなどを押してメニューを開く関数を渡すときに使用します。 <Menu onOpen={ handleOnOpen } /> Close menu handler ボタンやオーバーレイ(overlay)の部分などを押したときにメニューを閉じる関数を渡す時に使用します。 <Menu onClose={ handleOnClose } /> onOpenとonCloseはプロパティとして含めなくてもデフォルトで最低限の動作はしてくれます。 しかし, onOpenやonCloseを使うときは, 渡す関数内で必ず自身でメニューの開閉を処理するようにしなければなりません。 State change onStateChangeはコールバック関数を受け取り, メニューが開いているか閉じているかを検出することができます。onStateChangeに渡すコールバック関数の引数は, 最新の状態を保持するオブジェクトとなります。 let isMenuOpen = (state) => { return state.isOpen; }; <Menu onStateChange={ isMenuOpen } /> Close on Escape disableCloseOnEscプロパティを使用することで, Escキーを押した時にメニューが閉じる動作を無効にすることができます。これにより, レスポンシブメニューなどでメニューを常時開いておきたい場合などに便利です。 <Menu disableCloseOnEsc /> Custom keydown handler customOnKeyDownプロパティは, キーを押した際のメニューの状態を細かく制御することができます。例としては, 以下のようにMenuコンポーネントのインスタンスを複数使用している場合にEscキーを一度押すだけで全てのインスタンスを閉じる(メニューを全て閉じる)機能を実装する際に役立ちます。 const [areMenusOpen, setAreMenusOpen] = useState(false); const closeAllMenusOnEsc = (event) => { event = event || window.event; if (event.key === 'Escape' || event.keycode === 27) { setAreMenusOpen(false); } }; <MenuFirst customOnKeyDown={closeAllMenusOnEsc} isOpen={areMenusOpen} /> <MenuSecond customOnKeyDown={closeAllMenusOnEsc} isOpen={areMenusOpen} /> ※このプロパティを使用するとデフォルトのEscキーでメニューを閉じる機能が無効になるため, 例えばshiftキーを押したときにメニューを閉じる機能を実装した場合, Escキーは機能を失います。Escキーを使用したい場合は, 自身で関数内に処理を追加で記述する必要があります。 Overlay noOverlayプロパティを使用することで, デフォルトのオーバーレイ(overlay)をオフにすることができます。 <Menu noOverlay /> また, disableOverlayClickを使用することでオーバーレイ(overlay)を押した際のイベント(メニューが閉じるなど)を無効にすることができます。プロパティはブール値である必要があります。 <Menu disableOverlayClick /> <Menu disableOverlayClick={ () => shouldDisableOverlayClick() } /> Transitions noTransitionプロパティを使用することで, 全てのトランジションやアニメーションを無効にすることができます。 <Menu noTransition /> Custom icons customBurgerIcon, customCrossIconプロパティを使用することでデフォルトのバーガーアイコンとクロスアイコンを独自に置き換えることができます。 <Menu customBurgerIcon={ <img src="img/icon.svg" > } /> <Menu customCrossIcon={ <img src="img/cross-icon.svg" > } /> また, 各プロパティにfalseを渡すことでアイコン要素を無効にすることもできます。その場合は, ボタンなどを独自に作成してisOpenプロパティでメニューの開閉を制御します。 Custom ID and/or classNames MenuコンポーネントのプロパティとしてidとclassNameを指定することができます。 <Menu id={ "side-bar" } className={ "my-menu" } /> また, メニュー全体の各要素に対してプロパティとしてclassNameを指定することができます。(以下のclassNameは適当に考えたものです) <Menu burgerButtonClassName={ "burger-button" } burgerBarClassName={ "burger-bars" } crossButtonClassName={ "cross-button" } crossClassName={ "burger-cross" } menuClassName={ "burger-menu" } morphShapeClassName={ "burger-morph-shape" } itemListClassName={ "burger-item-list" } overlayClassName={ "burger-overlay" } /> また, html, body要素に対してclassNameを指定することもできます。 <Menu htmlClassName={ "html" } /> <Menu bodyClassName={ "body" } /> Focusing the first menu item デフォルトではメニューを開いた際にリストの最初の項目がフォーカスされた状態となっているため, disableAutoFocusプロパティを使用することで無効にすることができます。 <Menu disableAutoFocus /> Custom item list element メニューのリストは, nav要素にラップされており, ナビゲーションを使用しない場合はitemListElementプロパティでdivを指定します。 <Menu itemListElement /> Styling Menuコンポーネントは内部的にスタイルやアニメーションなどの処理を行います。 以下はバーガーメニューのスタイリングの例です。 CSS Menuコンポーネントは以下のクラスを持ちます。 /* バーガーボタンの位置とサイズ */ .bm-burger-button { position: fixed; width: 36px; height: 30px; left: 36px; top: 36px; } /* バーガボタンのバーのスタイル */ .bm-burger-bars { background: #373a47; } /* バーガーボタンのホバー */ .bm-burger-bars-hover { background: #a90000; } /* クロスボタンの位置とサイズ */ .bm-cross-button { height: 24px; width: 24px; } /* クロスボタンのカラー・形状 */ .bm-cross { background: #bdc3c7; } /* サイドバーのラッパースタイル - アニメーションが壊れる可能性があるため触るときは注意 */ .bm-menu-wrap { position: fixed; height: 100%; } /* サイドバーのスタイル */ .bm-menu { background: #373a47; padding: 2.5em 1.5em 0; font-size: 1.15em; } /* bubbleやelasticで必要なモーフの形状 */ .bm-morph-shape { fill: #373a47; } /* メニューリストのラッパースタイル*/ .bm-item-list { color: #b8b7ad; padding: 0.8em; } /* 個々のリストのスタイル */ .bm-item { display: inline-block; } /* オーバーレイ(overlay)のスタイリング */ .bm-overlay { background: rgba(0, 0, 0, 0.3); } CSS in JS Menuコンポーネントに以下のstylesオブジェクトを渡すことでスタイリングができます。 const styles = { bmBurgerButton: { position: 'fixed', width: '36px', height: '30px', left: '36px', top: '36px' }, bmBurgerBars: { background: '#373a47' }, bmBurgerBarsHover: { background: '#a90000' }, bmCrossButton: { height: '24px', width: '24px' }, bmCross: { background: '#bdc3c7' }, bmMenuWrap: { position: 'fixed', height: '100%' }, bmMenu: { background: '#373a47', padding: '2.5em 1.5em 0', fontSize: '1.15em' }, bmMorphShape: { fill: '#373a47' }, bmItemList: { color: '#b8b7ad', padding: '0.8em' }, bmItem: { display: 'inline-block' }, bmOverlay: { background: 'rgba(0, 0, 0, 0.3)' } } <Menu styles={ styles } /> 最後に なんかほぼ公式を和訳してちょっと脚色した感じなので, もし間違いなどあれば教えてい頂けますと幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Material UI v5 と Emotion の環境構築

以前 Material UI と Emotion を使った環境構築について記事を書いたのですが、Material UI が v4 から v5 にアップデートされたので、今回は以前の記事のリライトになります。 前提 【React】Material-UI v4 と Emotion を併用するときの環境構築の記事のリライトになります。 記事執筆時点で Material UI のバージョンは v5 なります。 npm ではなく yarn を使っています。 React の環境構築 まずは create-react-app の typescript テンプレートを利用してプロジェクトを作成します。今回はプロジェクト名を myapp にします。 $ npx create-react-app myapp --template typescript Material UI v5 と Emotion のインストール スタイリングシステムが変更され emotion or styled-components が必須になりました。今回はタイトルにある通り emotion をインストールします。 $ yarn add @mui/material @emotion/react @emotion/styled もし styled-components を使いたい場合は以下のコマンドでインストールできます。 $ yarn add @mui/material @mui/styled-engine-sc styled-components 一旦動くか確認してみましょう。不要なコードを消して App.tsx を以下に変更します。 myapp/src/App.tsx import React from "react"; import Stack from "@mui/material/Stack"; import Button from "@mui/material/Button"; const App: React.FC = () => { return ( <Stack spacing={2} direction="row"> <Button variant="text">Text</Button> <Button variant="contained">Contained</Button> <Button variant="outlined">Outlined</Button> </Stack> ); }; export default App; スタイリングの方法 v5 から makeStyle ではなく styled が推奨になったようです。以下の書き方でスタイルが反映されます。 myapp/src/App.tsx import React from "react"; import { styled } from "@mui/material/styles"; import Button from "@mui/material/Button"; const MyButton = styled(Button)({ backgroundColor: "red", "&:hover": { backgroundColor: "red", }, }); const App: React.FC = () => { return <MyButton variant="contained">ボタン</MyButton>; }; export default App; また sx props というの新しいスタリングの方法が導入されました。ユーティリティファーストな書き方ができます。 myapp/src/App.tsx import React from "react"; import { styled } from "@mui/material/styles"; import Button from "@mui/material/Button"; const App: React.FC = () => { return ( <Button variant="contained" sx={{ backgroundColor: "red", "&:hover": { backgroundColor: "red", }, }} > ボタン </Button> ); }; export default App; Emotion の css prop を使う 公式で推奨されているわけではないですが css prop を使いたい方は以下のように書くことができます(個人的に css prop を使っているので、以降のスタイリングも css prop を使っていきます)。 myapp/src/App.tsx /** @jsxImportSource @emotion/react */ import React from "react"; import { css } from "@emotion/react"; import Button from "@mui/material/Button"; const style = css` background-color: red; &:hover { background-color: red; } `; const App: React.FC = () => { return ( <Button variant="contained" css={style}> ボタン </Button> ); }; export default App; CRACO のインストール /** @jsxImportSource @emotion/react */ を毎回書くのは面倒なので CRACO をインストールします。CRACO は create-react-app の設定を上書きするときに使えるライブラリになります。 $ yarn add @craco/craco craco.config.js をルートに作り babel の設定を上書きします。 myapp/craco.config.js module.exports = { babel: { presets: [ [ "@babel/preset-react", { runtime: "automatic", importSource: "@emotion/react" }, ], ], plugins: ["@emotion/babel-plugin"], }, }; App.tsx ファイルから /** @jsxImportSource @emotion/react */ の記述を消してもスタイルが反映されるようになりました。 myapp/src/App.tsx import React from "react"; import { css } from "@emotion/react"; import Button from "@mui/material/Button"; const style = css` background-color: red; &:hover { background-color: red; } `; const App: React.FC = () => { return ( <Button variant="contained" css={style}> ボタン </Button> ); }; export default App; Theme を Material UI と Emotion で共有する Emotion の css prop で Material UI の Theme を使えるようにします。 まずは index.tsx を以下のように書き換えます。 myapp/index.tsx import React from "react"; import ReactDOM from "react-dom"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; import { ThemeProvider } from "@emotion/react"; import { createTheme, ThemeProvider as MUThemeProvider, } from "@mui/material/styles"; const theme = createTheme(); ReactDOM.render( <React.StrictMode> <MUThemeProvider theme={theme}> <ThemeProvider theme={theme}> <App /> </ThemeProvider> </MUThemeProvider> </React.StrictMode>, document.getElementById("root") ); reportWebVitals(); emotion.d.ts ファイルを作成し Emotion の Theme 型に Material UI の Theme 型を継承します。 myapp/src/types/emotion.d.ts import { Theme as MUTheme } from "@mui/material/styles"; declare module "@emotion/react" { export interface Theme extends MUTheme {} } App.tsx を以下のように書き換えます。Emotion からも Material UI の Theme が使えるようになっていますね。 myapp/src/App.tsx import React from "react"; import { css, Theme } from "@emotion/react"; import Button from "@mui/material/Button"; const style = (theme: Theme) => css` color: ${theme.palette.error.light}; `; const App: React.FC = () => { return ( <Button variant="contained" css={style}> ボタン </Button> ); }; export default App; Theme の拡張 次にテーマを拡張したいときの設定方法になります。 テーマの拡張には主に 3 パターンあると思っています。 Theme の上書きをしたいとき Theme に新規項目を加えたいとき すでにある Theme を拡張したいとき 順番に書いていきます。 Theme の上書きをしたいとき 上書きしたいだけならシンプルです。 createTheme で該当する値を上書きすれば問題ありません。 const theme = createTheme({ typography: { fontFamily: `"Meiryo", "メイリオ", sans-serif`, }, }); Theme に新規項目を加えたいとき 次に新しい項目を作成したいときです。 「Theme の上書きをしたいとき」と同様に createTheme に新しく加えたい値を書きます。 この時点では型定義のエラーが出るかもしれませんが、次の作業で対応します。 const theme = createTheme({ headerHeight: 100, }); 型の拡張をおこなます。 material-ui.d.tsという名前(任意の名前で OK)でファイルを作り、以下のように書きます。 Theme と ThemeOptions の両方で型を拡張します。 material-ui.d.ts import { Theme, ThemeOptions } from "'@mui/material/styles"; declare module "@mui/material/styles" { interface Theme { headerHeight: number; } interface ThemeOptions { headerHeight: number; } } すでにある Theme を拡張したいとき 基本的には、「Theme に新規項目を加えたいとき」と同じです。 以下は typography に font-size を計算する新しい関数を追加しています。 const theme = createTheme({ typography: { size: (n: number) => n * 4, }, }); material-ui.d.ts import { Typography, TypographyOptions, } from "@mui/material/styles/createTypography"; declare module "@mui/material/styles/createTypography" { interface Typography { size: (number) => number; } interface TypographyOptions { size: (number) => number; } } 型定義は myapp/node_modules/@mui/material/styles/createTheme.d.ts で確認できます。 以下のように型定義されているので、必要そうなところを拡張するといった感じです。 createTheme.d.ts /** 略 **/ export interface ThemeOptions extends SystemThemeOptions { mixins?: MixinsOptions; components?: Components; palette?: PaletteOptions; shadows?: Shadows; transitions?: TransitionsOptions; typography?: TypographyOptions | ((palette: Palette) => TypographyOptions); zIndex?: ZIndexOptions; unstable_strictMode?: boolean; } export interface Theme extends SystemTheme { mixins: Mixins; components?: Components; palette: Palette; shadows: Shadows; transitions: Transitions; typography: Typography; zIndex: ZIndex; unstable_strictMode?: boolean; } /** 略 **/ 一旦ここまでの対応を踏まえて、以下のように書き換えます。Theme の拡張を行えていることが確認できると思います。 myapp/index.tsx import React from "react"; import ReactDOM from "react-dom"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; import { ThemeProvider } from "@emotion/react"; import { createTheme, ThemeProvider as MUThemeProvider, } from "@mui/material/styles"; const theme = createTheme({ headerHeight: 100, typography: { fontFamily: `"Meiryo", "メイリオ", sans-serif`, size: (n: number) => n * 4, }, }); ReactDOM.render( <React.StrictMode> <MUThemeProvider theme={theme}> <ThemeProvider theme={theme}> <App /> </ThemeProvider> </MUThemeProvider> </React.StrictMode>, document.getElementById("root") ); reportWebVitals(); myapp/src/App.tsx import React from "react"; import { css, Theme } from "@emotion/react"; import Button from "@mui/material/Button"; const headerStyle = (theme: Theme) => css` height: ${theme.headerHeight}px; background: ${theme.palette.primary.main}; `; const textStyle = (theme: Theme) => css` color: ${theme.palette.text.primary}; `; const buttonStyle = (theme: Theme) => css` font-size: ${theme.typography.size(10)}px; `; const App: React.FC = () => { return ( <div> <header css={headerStyle}>ヘッダー</header> <p css={textStyle}>サンプルテキスト</p> <Button variant="contained" css={buttonStyle}> ボタン </Button> </div> ); }; export default App; material-ui.d.ts import { Theme, ThemeOptions } from "'@mui/material/styles"; declare module "@mui/material/styles" { interface Theme { headerHeight: number; } interface ThemeOptions { headerHeight: number; } } import { Typography, TypographyOptions, } from "@mui/material/styles/createTypography"; declare module "@mui/material/styles/createTypography" { interface Typography { size: (number) => number; } interface TypographyOptions { size: (number) => number; } } Global CSS の設定 Global CSS は Emotion の Global Styles 機能を使います。 Global を Emotion から import して、Global CSS を定義します。 myapp/src/styles/GlobalStyles.tsx import React from "react"; import { Global, css, Theme } from "@emotion/react"; const global = (theme: Theme) => css` html, body { width: 100%; height: 100%; margin: 0; font-family: ${theme.typography.fontFamily}; } `; const GlobalStyles: React.FC = () => { return <Global styles={global} />; }; export default GlobalStyles; 上記で作成したファイルを index.tsx で読み込むだけで Global な CSS を設定できます。 myapp/src/index.tsx import React from "react"; import ReactDOM from "react-dom"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; import { ThemeProvider } from "@emotion/react"; import { createTheme, ThemeProvider as MUThemeProvider, } from "@mui/material/styles"; import GlobalStyles from "./styles/GlobalStyles"; const theme = createTheme({ headerHeight: 100, typography: { fontFamily: `"Meiryo", "メイリオ", sans-serif`, size: (n: number) => n * 4, }, }); ReactDOM.render( <React.StrictMode> <MUThemeProvider theme={theme}> <ThemeProvider theme={theme}> <GlobalStyles /> <App /> </ThemeProvider> </MUThemeProvider> </React.StrictMode>, document.getElementById("root") ); reportWebVitals(); まとめ Material UI v5 における環境構築の話でした。 v4 から変更された部分も結構ありますので、参考にしていただけると幸いです。 参考 URL https://mui.com/ https://emotion.sh/docs/introduction https://github.com/gsoft-inc/craco https://zenn.dev/h_yoshikawa0724/articles/2021-09-26-material-ui-v5
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【JavaScript】変数と参照の振り返り①

はじめに Udemyの【JS】ガチで学びたい人のためのJavaScriptメカニズムの講座の振り返りです。 前回の記事 目的 変数についての理解を深める 本題 1.let, var, constの違い version 再宣言 再代入 スコープ 初期化 let ES6~ ✗ ◎ ブロック ✗ var ◎ ◎ ブロック undifined const ES6~ ✗ ✗ 関数 ✗ 再宣言:もう一度変数として宣言する 再代入:一度設定した値を変更できるか スコープ:varだけ関数スコープが生成 初期化:ホスティングのこと(varはundified)と表示される 以下VSコードで確認していきます。 // 再宣言 // letやconstは再宣言不可(エラーになる) let a = 0; let a = 0; // varは可能(b=1と表示される) var b = 0; var b = 1; // 再代入 // 以下0ではなくcに1を入れ直す let c = 0; c = 1; // constは再代入できない(定数?) const d = 0; d = 1; // スコープ // constやletの場合はブロックスコープが有効 { // 出力できない let e = 0; // varはブロックスコープが無視される var f = 0; } // ブロックスコープ外で書いても一緒 var f = 0; // 初期化 // 宣言をする前に値を取得しようとすると console.log(h); // letはエラーになる let g = 0; // varは初期値がundifinedなのでそのまま出力される(エラー発生しない) var h = 0; // varは非推奨 // ごちゃまぜにすると混乱する 2.変数とデータ型 JavaScriptのデータ型 型 英名 例 真偽値 Boolean true/false 数値 Number 1,2,3,,,, 文字列 String "HelloWorld" undifined Undifined null null シンボル Symbol 一意の値 BigInt BigInt 12n オブジェクト Object {a:'value'} 数値がNumberなの注意(intじゃない) 今日はここまで! 参考にさせて頂いた記事 【JS】ガチで学びたい人のためのJavaScriptメカニズム
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

何でもかんでも非同期通信に頼るのは良くない?

非同期通信とは? ネットワークなどでつながれているコンピュータ間で、送信者のデータ送信タイミングと受信者のデータ受信タイミングを合わせずに通信を行う通信方式・・・だそうです。 つまりどういうこと? あるタスクを実行している最中に、その処理を止めることなく別のタスクを実行できる通信方式、と言えそうです。 イメージとしてはこうなります。 非同期通信の利点 そもそも何がいいのでしょうか? よく聞くのは、非同期はwebページの一部のみを更新するための機能として使われているということです。 ページ全体を読み込みしなくて良いので早い。これがメリットだと紹介されています。 サーバーのトラフィックを減らし、スピードを上げる レイジーローディング 帯域使用量の削減 フォームの検証 などが挙げられるかと思います。 サーバーのトラフィックを減らし、スピードを上げる アプリケーションがデータなしでレンダリングすることを可能にし、リクエスト内部のサーバー・トラフィックを削減します。 その結果、Webサイトの訪問者が白いウィンドウを見たり、ページの更新を待つ必要がなくなります。 レイジーローディング 必要なセクションのみをロードすることを支援し、残りのセクションはユーザーが必要とするまで遅延させます。 つまり、ユーザーは、ウェブサーバーに非同期呼び出しを行うことで、ページ全体の読み込みを待つ必要がありません。 帯域使用量の削減 ページのコンテンツ全体を送信するのではなく、パーティクルコンテンツを取得することで、サーバーの帯域幅を有効に利用することができます。 つまり、データベースとのやり取りを、ページをリロードすることなくバックグラウンドで実行することができるようになります。 フォームの検証 従来のフォーム送信では、送信後にクライアントサイドの検証が行われていましたが、非同期通信では、正確かつ即時のフォーム検証が可能になります。 非同期通信の利点まとめ つまり、ページ全体をリロードしなくていいから通信量が少なくすむよ、と言っているわけです。 イメージとしてはこうなります。 非同期通信の欠点(注意点) なんだいい事ばかりじゃないですか ・・・本当に?? オープンソースである JavaScript依存している 特定の状態をブックマークすることが困難 伝送効率が悪い オープンソースである ソースの閲覧が許可されており、誰でもAjax用に書かれたコードソースを見ることができます。 このため、他の技術に比べて安全性が低いです。 JavaScriptに依存している JavaScriptにかなり依存しているため、JavascriptsやXMLHttpRequestをサポートするブラウザでなければ、利用できません。 特定の状態をブックマークすることが困難 動的なWebページのため、ユーザーはアプリケーションの特定の状態をブックマークすることが困難になります。 ユーザーの視点に立つと、ブラウザの「戻る」ボタンをクリックしたときに、ページの前の状態に戻るのではなく、ページ全体に戻ることがあります。 また、JavaScriptだけで作られたページは、Googleや他の検索エンジンにもインデックスされない可能性があります。 伝送効率が悪い 非同期通信方式は、送信者が通信データにデータの始まりを示す「スタートビット」とデータの終わりを示す「ストップビット」という信号を付加してデータを送信し、受信者は「スタートビット」を受信するとデータの受信を開始し、データ受信中に「ストップビット」を受信するとデータの受信を終了するという方法で行っています。  つまり、「スタートビット」と「ストップビット」というデータ内容とは無関係の冗長なデータも送信する必要があるため、送信タイミングと受信タイミングを合わせて通信を行う同期通信に比べて送信するデータ量が多くなり伝送効率が悪くなってしまいます。 え?伝送効率が悪い?? どう言う事でしょうか?早いんじゃなかったの? イメージではこうなります つまり超軽い処理では、かえって遅くなる可能性もあり得るということです。 とは言え、ページ全体を読みこむことに比べればデータ量は少なくなる事が多いと思いますが。。 非同期通信の欠点(注意点)まとめ なんにせよメリット・デメリットがあるようなので、何でもかんでも非同期に頼るのではなく、必要に応じで使用する事が大切なんですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む