
今日は、もりけん塾のJavaScript課題1を終えて学んだことをアウトプットしていきます。
こんにちは。Webコーダーのはるです。
7月から朝の少しの時間を使ってJavaScriptの勉強を始めました。
具体的には、所属している「もりけん塾」でハンズオン課題 に取り組み、レビューをいただいています。
今日は、課題1が終わったので、早速アウトプットをしていきます!
【もりけん塾】JavaScript課題 1で学んだこと まとめ
今回、取り組んだ課題はこちらです。
(もりけんさんのJavaScriptハンズオン課題より)
この課題から学んだこと
・appendChild, innerHTML, insertAdjacentHTMLの違い
・処理を書く順番
一つずつまとめていきます。
textContent, innerHTML, innerTextの違い
この課題では、
document.createElement('li');
で <li>要素を作成したあとに、<li>の中身を書き換えました。
要素の中身を書き換えるメソッドには textContent , innerHTML , innerText があります。
これらのメソッドに共通しているのは、子要素のテキストを”完全に置き換える”という点です。(JavaScrip本格入門 本より)
どういうことかというと、例えば以下のようなHTMLがあったとき
<div id="js-text">
<p>書き換えます</p>
</div>
JSでdivを取得して、子要素を置き換えてみます。
const text = document.getElementById('js-text');
text.textContent = '<a href="#">リンクです</a>';
/* または */
text.innerHTML = '<a href="#">リンクです</a>';
/* または */
text.innerText = '<a href="#">リンクです</a>';
どちらの場合も、もともとあった<p>書き換えます</p>の要素は完全に消えて、<a>リンクです</a>に置き換わります。
しかし、 出力される時に「テキストを解析してから追加されるか」に違いがあるのでまとめます。
textContent
textContentは、指定されたテキストを「プレーンなテキスト」として認識します。
先程の例で言うと、
<a href="#">リンクです</a>
とブラウザにタグごと表示されるわけです。
innerHTML, innerText
innerHTMLは、指定されたテキストを解析して「HTML」として埋め込みます。
先程の例で言うと、
リンクです
この’リンクです’の部分に実際にリンクがついて表示されます。
innerTextは、指定されたテキストを解析して「文字列」として埋め込みます。これは、textContentと似ていますがレンダリングされた文字列を返す、と言うところが異なっています。
textContentを優先させよ
一般的に、innerTextよりtextContentを優先させるべき、と言うことを学習しました。
なぜならテキストの解析がないので動作が高速だからです。
解析について、StackOverflowにはこのようにあります。
Moreover, since innerText takes CSS styles into account, reading the value of innerText triggers a reflow to ensure up-to-date computed styles. (Reflows can be computationally expensive, and thus should be avoided when possible.)
(さらに、innerTextはCSSスタイルを考慮しているため、innerTextの値を読み取ると、計算されたスタイルが最新のものになるようにリフローが発生してしまいます。(リフローは計算コストがかかるため、可能な限り避けるべきです。)
ここでReflow(リフロー)と言う言葉を知りました。
これは、レイアウトやポジションなどを再計算してから表示するものです。
Reflowが起こると、その要素の親子・さらにその親まで再計算されてしまうので、著しくパフォーマンスが低下してしまいます。Line Enginneringの記事には、
結局はページ全体を再び描画することとほぼ同じです。
と書かれています。
そのためtextConetntプロパティを優先させるべきと学びました。
appendChild, innerHTML, insertAdjacentHTMLの違い
JS課題に戻り、作成した<li>を元々あった<ul>の中に挿入します。
const ul = document.getElementById('js-lists');
ul.appendChild(li);
このように結果、appendChildを選んだわけですが、
他のメソッドとの違いについてStackOverflowにはこのようにあります。
The appendChild methods adds an element to the DOM.
The innerHTML property and insertAdjacentHTML method takes a string instead of an element, so they have to parse the string and create elements from it, before they can be put into the DOM.
(appendChildメソッドは、DOMに要素を追加します。
innerHTMLプロパティとinsertAdjacentHTMLメソッドは、要素ではなく文字列を受け取るので、DOMに入れる前に文字列を解析し、そこから要素を作成する必要があります。)
つまり、単純に要素を追加するappendChildに比べて、insertAdjacentHTMLは与えられた要素を解析してから追加になるためパフォーマンスが劣ると言うことです。
innerHTMLも先ほども解説したように、与えられた要素を解析してからHTMLを返します。
処理を書く順番
最後に、処理を書く順番についてレビューをいただいたのでまとめます。
これは、とても基本的なところなのですが…
私が最初に書いたコードはこちらです。
'use strict';
const ul = document.getElementById('js-lists');
const li = document.createElement('li');
ul.appendChild(li);
li.textContent = 'これです';
<li>を追加してから、textContentで書き換えてしまっています。
- <li>を作成
- <li>のテキストを書き換える
- <ul>に<li>を挿入する
'use strict';
const ul = document.getElementById('js-lists');
const li = document.createElement('li');
li.textContent = 'これです';
ul.appendChild(li);
このように修正してApproveとなりました。基礎的……
あとがき
初めてのレビューを終えて、改めて書いたコードを添削してもらえることのありがたみを噛み締めました。
速度は遅いかもしれませんが、1つ1つの課題を自分なりに深堀して、着実に力をつけていきたいと思います!
今日は以上です。
【もりけん塾で学習中です!】
Thanks:師匠「もりけんさん」(@terrace_tec)
もりけんさんのHPはこちら