【もりけん塾】JavaScript課題1で学んだことまとめ

JavaScript

今日は、もりけん塾のJavaScript課題1を終えて学んだことをアウトプットしていきます。

こんにちは。Webコーダーのはるです。

7月から朝の少しの時間を使ってJavaScriptの勉強を始めました。

具体的には、所属している「もりけん塾」でハンズオン課題 に取り組み、レビューをいただいています。

今日は、課題1が終わったので、早速アウトプットをしていきます!

【もりけん塾】JavaScript課題 1で学んだこと まとめ

今回、取り組んだ課題はこちらです。


(もりけんさんのJavaScriptハンズオン課題より)

この課題から学んだこと

・textContent, innerHTML, innerText の違い
・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で書き換えてしまっています。

問題なく動きはするのですが、以下の順番の方が自然です。
  1. <li>を作成
  2. <li>のテキストを書き換える
  3. <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はこちら

タイトルとURLをコピーしました