*概要 [#z1d83c54] -ユーザが直接見る画面の設計 ウェブ開発がバグったときのデバッグ情報は、以下で得ることができる。 - F12の左上のエラー←重要!!!!!!!!!!!!フロントエンド側でキャッチできるログ - Stackdriverのログ←サーバサイドのログ。 placekittenというサイトがあって、横幅縦幅を指定してかわいい猫の画像をダウンロードできる Vue 「ヴュー・ドット・ジェイエス」と読みます。 JavaScript フレームワークの一つで、主に、MVC(Model View Controller)モデルの View 層を扱います。 tokenをデコードしたあとのclaimsは、もしそれが不正ならばNone, そうでなければmap<string, string>が返ってきて、sub=uid, isser, audien ce, issued-at time, expiration timeなどの情報が得られる。特にsubが重要で、これがアクセスしてきたユーザのuidなのでキーとして安全に利用可能 フロントエンドでユーザが得るgetIdToken expireしていなければ…って書いてあるということはおそらくサーバから撮ってきて、ローカルに保存しているのだろうと思う。 Returns a JSON Web Token (JWT) used to identify the user to a Firebase service. Returns the current token if it has not expired. Otherwise, this will refresh the token and return a new one. 認証トークンの送信はRFC 7235で規定されている Authorization ヘッダを使うと良いです。Basic認証とかDigest認証で使うやつですね。 実は Basic や Digest の他にRFC 6750で Bearer というスキームが登録されています。単一の文字列を ... クライアントがトークンを HTTP リクエストに含めて送信し、サーバはトークンを検証してリソースへのアクセスを許可したい Authorization: Bearer トークン ヘッダでトークンを送る API あるよね、ああいうやつ 疑問 Authorization: Bearer ヘッダは OAuth と関係しているらしいけど、ログインに OAuth を使わない API でも使っていい?→良い。RFC 6750には汎用的なHTTP認可に使って良いと書いてある bearer が何を意味するのか?を考えたことはなかったんですが、言われてみると気になります。 辞書を引くと ・運ぶ人[もの],運搬人 ・持参人 などという意味があるようです。 FirebaseのAPI keyなどをハードコードしたくない場合 webpackの機能を使って API_KEY などを環境変数から流し込む方法もあります https://qiita.com/shora_kujira16/items/95216245ecf06c4cd16d $('#logged-in').hide(); $('#logged-out').show(); でdivを全部見せたり消したりを制御することができる locationはJavascriptのオブジェクト。変数もあるしメソッドもある。たとえば、JSからリダイレクトみたいなことをしたい場合は、 例えば、http://example.comへ遷移したい場合、 location.href = 'http://example.com'; とするか、 location.assign('http://example.com'); とします。両者の違いですが、location.href property vs. location.assign() methodによると速度的な違いからlocation.href = '...'を使う方が良いとする人が多いようです。 また、上の2つの方法はページ遷移がブラウザの履歴に残るため、遷移後に戻るボタンで元のページヘ戻ることができますが、 location.replace('http://example.com'); とした場合、ブラウザの履歴に残らないため、戻るボタンで元のページヘ戻ることができません。 この記事では、3種のクラス内関数について説明します。 - 通常のメソッド(インスタンスメソッド)person1.self_introduction()、もしくはPerson.self_introduction(person1)のようによびだす。前者とと後者は完全に同じ - staticmethod(静的関数) これはインスタンスに依存しない関数。なのでclassないぶのdefであってもselfを第一引数にする必要はない - classmethod theadタグは、表の中でも見出しの部分になるやつ。wikiとかでも表の一番はじめの列にhってつけけどあれと同じこと。 JSを使うと、div id = "notes-containier"となっている部分を変数のように扱って事由に変更することができる! yukicoderはこんな間じで削除を押すとproblem-idと対応させてポップアップが出るようになっている <a class="deleter" href="#" data-problem-id="1979" data-title="天秤とニセモノの硬貨"><i class="fa fa-trash-o"></i>削除</a> *フレームワーク [#g08727f0] **.next [#vb099a59] -.next には next/image という画像を最適化するコンポーネントがついている(画像のサイズとか) --静的コンポーネントの場合は、.next/static/ どこかに hash として全部保存される --外部の GCS などのサービスを使う場合、next.config.js でホワイトリストに入れておけば外部サービスの画像も最適化してくれる(ただし悪意ある他人による乱用に注意) *HARファイル [#ze2d3c0e] -HARファイルは実際のところ裏はJSON 朝昼晩で比較して、どこのネットワークが遅くなっているのかを確認するなどする。 自動で朝昼夜比較するとか、スマホとPCで比較するとかしてパフォーマンスを比較する方法がある なお、Auditソフトなどを使うことでJSまとめろとかgzip で遅れとかキャッシュさせろとか使ってないCSSどうにかしろとかいろいろ言ってくれう *DOM [#ga6429e7] **DOM 操作基礎 [#w5c009a3] -HTML を木構造として表したブラウザ内での表現。 --root は document, DOM 要素 = ノード -動的なウェブページは、DOM のプロパティなどを変更することで HTML を調整している。 -DOM API というもので統一的に変更を扱えるようになっている。 --ブラウザとやり取りするときのプロトコルようなもの -document 自体がオブジェクト -ノードタイプ --Node.ELEMENT_NODE (タグなど), Node.TEXT_NODE, Node.COMMENT_NODE などが定義されている。 --node.nodeType 変数でそのノードのノードタイプが取れる。 -document.head, document.body は直でとれる -document.getElementById("main") とすると、id="main"の要素がとれる --F12 の Console で全く同じコマンドを打つと、オブジェクトが帰るのが見れる -e.getElementByTagName("p") などとすると、p タグの DOM 要素が全部返る(HTMLCollection という配列みたいなものが帰ってくる。) -e.getElementByClassName("apple") などとすると、クラスが apple の要素が返る。 -e.querySelector("p.apple") などとすると、p タグ apple クラスの最初の DOM が返る(これに使い方は限らない) --tag.class#id // "apple"クラスを持つ最初の要素 const apple = element.querySelector(".apple"); // "orange"クラスを持つ最初の<p>要素 const orangeParagraph = element.querySelector("p.orange"); // "apple"クラスと"banana"IDをどちらも持つ最初の要素 const appleBanana = element.querySelector(".apple#banana"); -全部返すためには、e.querySelectorAll を使う -まず、<ul>a<li>x</li><li>y</li><!-- hoge --></ul>のようにした場合、ul の子ノードは以下のようになる。空文字列が挿入されるのがポイント --テキストノード: a --<li>x</li> --テキストノード: (空文字列) --<li>y</li> --コメント --テキストノード: (空文字列) -element.childNodes; とすると、NodeList という array-like な配列が帰ってくる --Array.from(nodes) とするとちゃんとした配列になる -element.classList とすると、その要素のクラスを全て獲得できる(スペース区切りで複数設定できる) --何故か classList は push ではなく add / remove で追加・削除ができる。contains でクラスの存在確認ができる。何に使うのか不明だが、toggle という class がセットされていれば取り除き、取り除かれていたらセットする関数もある。 -自分の親のノードにアクセスする場合、parentNode という変数に核の言うされている -自分の左右のノードにアクセスする場合、nextSibling という変数に格納されている。 -node.textContent 変数には、そのノードから下に再帰的に走査した、含まれる TEXT_NODE の concat が入っている -node の走査は、for (const node of children) で行う。 -.createTextNode, .createElement, appendChild などを利用して、目的の位置に DOM 要素を追加することも可能。 --特定の位置に入れたい場合、parent.insertBefore(newNode, existingNode) で行う。 -parent.removeChild(child) で削除することも可能(ノード全体を削除しているようにみえるけど計算量大丈夫なんか?) -id, class 以外の属性は、getAttribute, setAttribute, hasAttribute, removeAttribute などで確認することができる。 -document.getElementsByClassName() の結果は、動的にリストが変化する。途中でリストの結果を変えるとリストから消え去ってループすら回らなくなるので、静的なリストを得たい場合には querySelectorAll を使うと良い。 **DOM イベント [#f29febdd] --DOM のイベント (click など) に応じて何らかの処理を行う割り込み処理 --あるノードでイベントが発生すると、3つのフェーズに別れて処理する ---キャプチャフェーズ→ root からイベント発生要素 ---ターゲットフェーズ→関数実行 ---バブリングフェーズ→root に戻る --注意: バブリングフェーズで、親の全同等イベントが発火する!!(モダンブラウザのデフォルト動作) ---なので、div の中に video があり、video がクリックで動画再生、div でクリックで非表示のハンドラが設定されている。このとき、video をクリックすると、video 再生→バブリングフェーズで div に移動 →div のクリックで非表示、といった風になって動画が即座に閉じられてしまうといった不具合が発生する。 ---stopPropagation を使うと、バブリングフェーズの伝播を無視できる。 -element.addEventListener(eventName, func, [options]) のようにする。eventName は事前に決まったものしかできない (click, mouseover, DOM の構築終了イベント DOMContentLoaded など) --option には、例えば once: true のように一回だけしか発火しないようにするものなどがある --option には、例えば once: true のように一回だけしか発火しないようにするものなどがある。他には、capture というバブリングフェーズではなくキャプチャフェーズでイベントを発火させるものもある(つまり、通常は上流から伝播して下位から発火するが、そのまま上流から発火することになる) -removeEventListener() でコールバックを削除できる。option は capture の値だけ一致させる必要がある。 -event listener 内部で、click したら通常何か起きるはずのものについて、逆に何も起こさないようにするために event listener を設定することが出来る。その場合、e.preventDefault() とすれば、たとえばクリックボタンはクリックできないようになる。 -button や form タグは、element の要素に checked や value などのその機能に特化した変数を有する。 -あと、button, form などはいちいち element を指定してデータをとって…とするのはめんどいほど頻出するので、document.forms.{form name} のようなショートカット的なアクセス方法がある。 -addEventListener は下位 element 全てに伝播しながら発火する -addEventListener は下位 element 全てに伝播し、戻りながら発火する(capture がデフォなら) --ev.target が今発火している element, ev.currentTarget が発火の大本となったイベントが登録された element (currentTarget のほうが常に DOM の上流) |