現在、もりけん塾にてJavaScriptを勉強させていただいております。その記録。
今回は課題27についての備忘録です。
考え方が間違っている箇所もあるかと思いますが、お気づきの際はご指摘いただければと思います。
課題27について
仕様
index.html
ページ遷移時に 学習の為のローカルストレージのトークンを参照して もし {token: far0fja*ff]afaawfqrlzkfq@aq9283af}
の値があれば 作ったコンテンツUI画面を ローカルストレージにそれがなければログイン画面(login.html
)に遷移するように作ってください
ローカルストレージの有無はコンテンツページ遷移時に確認してください
- 開発ツールのApplication -> localStorageの中の値を削除してリロードした際もログイン画面に遷移するはずです
- またログイン画面からurlをコンテンツページのそれに変更してもちゃんと挙動ができていること
制作物
コードはこちらから(codesandbox)実装内容
トークンの確認
index.htmlページ(コンテンツページ)遷移時、トークンが埋め込まれているか確認する。
当初、news.jsの適当なところに下記を記載しました。
//もしindex.html遷移時、ローカルストレージにトークンがなければ、ログインページへ遷移する
if(!localStorage.getItem('token')) {
window.location.href = "./login.html"
}
いただいたレビュー①
ログインページをリロードするとコンテンツページが一瞬見えてしまうとレビューをいただく。(トークンがない場合はコンテンツページが表示することはない)
原因を調査した結果、上記トークン確認コードの実行タイミングが遅いせいかな?と思いました。つまり、index.htmlを表示させる際、早いタイミングでトークンの確認をし、どの画面を表示させるか判断させたい。
考えた結果、JSファイルに書くのではなく、index.htmlに直書きすることにしました。
(tokenチェックのみでJSファイルを分け、一番上に差し込みしてみたがそちらでは改善がみられなかったので直書きにした)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link href="./css/news.css" rel="stylesheet" />
//ここに追加
<script>
if (!localStorage.getItem("token")) window.location.href = "./login.html";
</script>
//ここまで
<script src="./js/news.js" defer></script>
<title>TerraceTechフロントエンドエンジニア養成所</title>
</head>
<body>
<div class="container">
<div class="logout_btn" id="js-logout-button-area">
</div>
<div id="js-newsWrapper" class="newsWrapper">
<ul id="js-tabs" class="news_tabs"></ul>
</div>
</div>
</body>
</html>
その他レビューPOINT②
ブラーイベントでは入力後にどこかをクリックして、バリデーションが通ったか確認する必要があるが、pointer-eventsを使用すれば入力後に直接送信ボタンを押すことができる。
/* .submit_button {
width: 100%;
background: #000;
font-size: 1rem;
line-height: 1.2;
font-weight: 300;
height: 60px;
color: #fff;
border-radius: 30px;
cursor: pointer;
}
.submit_button:disabled {
background: #ccc;
cursor: not-allowed;
} */
.submit_button {
width: 100%;
background: #000;
font-size: 1rem;
line-height: 1.2;
font-weight: 300;
height: 60px;
color: #fff;
border-radius: 30px;
cursor: pointer;
pointer-events: auto; //here
}
.submit_button:disabled {
background: #ccc;
cursor: not-allowed;
pointer-events: none; //here
}
その他レビューポイント③
コンテンツページのログアウトボタン表示のタイミングが他の要素と合っていない。
ログアウトボタンはあとから追加した要素なのですが、HTMLで直接追加していました。なので、コンテンツページが表示されるとすでに存在してしまう。ご指摘を受け、その通りだなと感じたので、ログアウトボタンもJS側から追加に変更しました。
また、ログアウトボタンのクリックイベントの関数名について、当初、logoutButtonEvent()という名前を使用していましたが、関数名には動詞がつくべきだとご指摘いただき、addEventForLogoutButton()という名前に変更しました。(完全にいただいたアイディアをそのまま採用させていただいた..)
//ログアウトボタンを作成
const renderLogoutBtn = () => {
const logoutButton = createElementWithClassName('button', 'logoutButton');
logoutButton.id = 'js-logout-btn';
logoutButton.textContent = 'Logout';
logoutButtonArea.appendChild(logoutButton);
}
//ボタンのクリックイベント
//押下すると埋め込まれたトークン削除
const addEventForLogoutButton = () => {
const logoutButton = document.getElementById('js-logout-btn');
logoutButton.addEventListener('click', () => {
localStorage.removeItem('token');
window.location.href = './index.html';
});
}
その他レビューPOINT
トークンのセットをloginVerification()関数の中で行なっていたが、この関数はログイン認証をすることが目的で、その結果は別の関数で実行するべきだとご指摘いただきました。そのため、init()関数にて、もしverificationResult()がTRUEだったら、トークンをセットする流れに変更しました。
const init = async () => {
const verificationResult = await loginVerification();
if (verificationResult) {
const token = verificationResult.token;
localStorage.setItem("token", JSON.stringify(token));
window.location.href = "./index.html";
} else {
window.location.href = "./loginFailure.html"
}
}
後記
ログイン状態を保持するというのが、トークン確認コードを書いただけで満足していたのが、レンダリングのタイミング等も関わってくるんだととても勉強になりました。言われてみて気づいたので、そういった不安定な動きも実装者として気づくべきだなと思いました。
c.sakyou