【もりけん塾】JavaScript課題1 まとめ
webコーダーのsaco @sacocco_sacoya です。
所属しているもりけん塾にてマークアップエンジニアの方がフロントエンドエンジニアになる為の課題1に挑戦しました。
備忘録&勉強になったことをまとめていきます。
課題内容
このDOMをhtml内のulの中に差し込んでください
<li>これです</li>
作成手順
- <ul>を取得する
- <li>を作成する
- <li>にテキストを追加する
- <li>を<ul>の中に差し込む
提出コード
//get:ID='js-lists'
const ul = document.getElementById('js-lists');
//create <li></li>
const li = document.createElement('li');
//add:text -> これです
li.textContent = 'これです';
ul.appendChild(li);
まず要素を取得するメソッドを調べました。
その後、要素を作成するメソッド、テキストを挿入する方法、要素を追加する方法など、目的に合うメソッドを調べながら構築していきました。
プルリクエスト&レビューにて勉強になったこと
修正内容のコミットIDを付与してコメントする
レビューに対して行った修正はコミットID(コミットハッシュ)を付与することで、レビュワーの方はそのリンクをクリックすればすぐにコミットを確認することができる。
↓コミット履歴から赤枠のマークをクリックでコピー
↓プルリクエストのコメント欄へコピペするだけでリンクになりました。
最後の行に改行を設定しておくこと
ファイルの末尾に改行を設定しておくべきと初めて知りました。
行というのは文字+改行までがセットで、次のコード追加時に最後の行に改行をいれると、例えば「}」「}\n」となり\nが追加されるため、本来変更していないはずの行がハイライトされてしまい、レビュワーに認知不可がかかってしまうので、最後の行には改行を追加しておく必要があるそうです。
これらの問題はVs Codeの設定だけで解決することを知りました。
設定(⌘ + ,)の検索で、insert final と検索すると↓のチェックボックスが出てくるのでチェックします。
この設定で最後の行に自動的に改行が追加されるようになりました。
クローズしたプルリクエストの確認方法
プルリクエストタブを開いて、「Closed」をクリックすると解決済のプルリクエスト一覧を見ることができる。
(記念すべきfeatureブランチを削除したあと、あれ?!頂いたレビューの履歴も消えた!?と思って一瞬焦りました。)
疑問に思った点について
提出課題では、要素の取得や挿入を1つずつ分けて行いましたが、以下のコードでも同じ結果が得られることに気がつきました。
document.getElementById('js-lists').innerHTML = '<li>これです</li>';
このコードのメリットとしては、シンプルで直感的であり、短くて読みやすいということ。
デメリットとしては、innerHTMLによる既存内容の上書きにより、指定した要素の中身のノードが全て上書きされてしまうこと。
テキストや要素を直接操作するため、XSSのリスクが高まる。
innerHTMLでは再解析と再描画が行われるため、パフォーマンスが低下する恐れがある。
提出のコードは若干冗長ではあるものの、DOM操作メソッドを利用する方がセキュリティ上も安全であり、パフォーマンスでも有利であることが多いとのことでした。
DOMメソッドとは
HTML要素に対して実行できるJavaScriptメソッド。
.getElementById()や.querySelector(selector)など。
備忘録
以下、課題に取り組むにあたって調べたことの備忘録です。
要素を取得できるメソッド
JavaScriptで要素を取得できるメソッドを調べました。
document.getElementsByTagName()
HTMLタグ名を取得できる(<ul>とか<p>とか<a>とか)
document.getElementById()
指定したidと一致する要素を取得できる。
document.getElementsByClassName()
指定したclass名と一致する要素を取得できる。
document.querySelector()
セレクタ(class、id、タグ名、属性)に一致した最初の要素を取得してくれる。
document.querySelector(‘#id’)やdocument.querySelector(‘.class’)などとしてセレクタの記号を記述する必要がある。
document.querySelectorAll()
セレクタに一致した要素を全て取得してNodeListとして返す。
document.querySelector()で要素を取得するよりも、getElementById()やdocument.getElementsByTagName()で(直接的に)要素を取得した方が処理が高速だが、実際のパフォーマンス差は一般的なウェブページでの使用においてはほとんど気にならない程度であり、コードの可読性やメンテナンス性を考慮して適切なメソッドを選ぶことが重要。
テキストを追加するプロパティ
innerText
指定された要素のテキストを設定または取得できる。
document.getElementById("js-lists").innerText = "テキスト";
textContent
要素の中の全てのテキストコンテンツを設定または取得できる。
document.getElementById("js-lists").textContent = "テキスト";
innerHTML
要素の中のHTMLコンテンツを設定または取得できる。
要素内にHTMLタグを含むテキストを追加したい時に便利。
document.getElementById("js-lists").innerHTML = "<li>テキスト</li>";
innerTextとtextContentの違い
innerText
- 表示されているテキストのみを対象
→display:noneや、visibility:hiddenなど非表示の要素は取得することができない。
- CSSの影響を受ける
→white-spaceプロパティの設定により、改行や空白文字の扱いが変化する。
(white-space: pre;とすると改行や空白がそのまま取得され、white-space:nowrap;とすると改行されず1行で取得される、という具合)
- 再描画(※)が発生するのでパフォーマンスに影響がある場合も
→要素の再描画が行われるため、小さな変更であれば問題ないが、複数箇所の変更となるとパフォーマンスが低下する場合がある。
※)DOMの変更(ここではテキスト変更)、レイアウトの再計算[リフロー](要素の位置やサイズの再計算)、リペイント(背景色、テキストの色など視覚的な反映)
textContent
- 全てのテキストが対象。
→innerTextと違い、非表示の要素も取得することができる。
- CSSの影響を受けない
→innerTextと違い、全てのテキストをそのまま取得する
- パフォーマンスが良い
→innerTextと違い、再描画が発生しないので多くの要素に指定してもパフォーマンスに影響を与えにくい
innerTextとtextContentの使い分け
非表示の要素も取得したい場合や、パフォーマンスを考慮する場合→textContent
非表示の要素は取得せず、ユーザーが実際に見えている要素だけ取得したい場合→innerText
要素を追加するメソッド
append()
指定された要素やテキストノードを末尾に追加するためのメソッド。一度に複数追加できる。戻り値を返さない。新しいメソッドで、古いブラウザではサポートされていない場合がある。
appendChild()
指定された子ノードを特定の親ノードの末尾に追加するためのメソッド。一度に追加できるのは1つの(単一の)ノードだけ。テキストノードも追加できる。追加されたノードを戻り値として返す。長い期間使われてきたメソッドで、ほぼ全てのブラウザで対応している。
append()とappendChild()の違い
append()を利用するのに向いているのは、
- 複数のノードやテキストを一度に追加したい場合
- テキストノードを追加したい場合
今回の課題例では、append(li)としてもappendChild(li)としてもどちらでも結果は同じだが、複数のノードを追加するのではなく単一のノードを追加したかったのでappendChild()を利用しました。
感想
要素を追加する、というシンプルな課題ですが、この課題をクリアするにあたって色々なメソッドやプロパティについて学ぶことができました。
また、初めてGitHubのプルリクエスト機能を実際に利用することができ、挙動のあれこれを学ぶことができて嬉しかったです。
他にもこの課題を通じて、StackBlitzというオンラインコードエディタとGitを連携させる方法など、ここには書ききれない学びがありました。
4月の入塾からGitを学ぶところから始め、課題1の提出までかなり時間がかかりましたが第一歩を踏み出せた感じがして嬉しいです。
課題2も引き続きまとめながら挑戦していけたらなと思います。
主にレビューをしてくださったはせがわさん @starsurferz、もりけんさん @terrace_tech、記事を参考にさせていただいたはるさん @fuwafuwahappy、さえ @sae_progさん、ありがとうございました。
もりけん塾とは?
フロントエンドエンジニアを目指す方の無料コミュニティ「もりけん塾」。
「無料でJavaScript教え合うフロントエンドコミニュティ」です。
詳しくはこちら↓↓
https://kenjimorita.jp/morikenjuku
もりけん先生のTwitter↓↓
https://twitter.com/terrace_tech
参考記事・動画
【もりけん塾】GitHubでコードレビューを受けるときのお作法まとめ | <>haru log
https://happy-making.com/github-review/
【もりけん塾】JavaScript課題1で学んだことまとめ | <>haru log
https://happy-making.com/javascript-lesson01/
【もりけん塾】#JS課題1・2 | フロントエンドエンジニアの積み上げブログ
https://itosae.com/archives/541
よしかわのブログ【もりけん塾】JS課題の振り返り その1 | よしかわのブログ
https://yoshikawa-blog.com/reflection-on-learning-01/
[JavaScript] HTMLを動的に作成する方法
https://qiita.com/s_ryota/items/785e0b99c53c4132a9c1
要素の取得方法まとめ
https://qiita.com/amamamaou/items/25e8b4e1b41c8d3211f4
JavaScriptのtextContents、innerText、innerHTML: 違いhttps://www.wantedly.com/companies/company_1071330/post_articles/865343
GitHubのコードレビューを受ける際に気をつける事
https://zenn.dev/keitakn/articles/github-code-review-reviewee
気づかぬうちに食らってるかも?!NodeListと配列の違い