Open13

HTML再入門

ken7253ken7253

HTMLを改めて理解するための記事についてのまとめ

ken7253ken7253

要素の分類

HTMLの要素には継承関係があり、上位のプロパティやメソッドを引き継ぎます。
下記は継承関係を一部抜粋した図です。スペースの関係ですべての項目は記述できていませんが、大まかに知っておくと理解が進みやすいであろうものを抜粋して掲載しています。

HTMLの継承関係を表した逆ツリー構造の図

あくまでこの図はDOMインターフェイスの継承関係を表した図であるため、Windowオブジェクトを最上位とするDOMツリーとは異なることに注意してください。

ken7253ken7253

EventTarget

すべてのDOMインターフェイスはEventTargetを継承しています。
正確に表現すると、EventTargetObjectを継承しているためJavaScript的には最上位ではありませんがDOMインターフェイスとしてはEventTargetが最上位となります。

普段DOMを触っているとあまり聞き馴染みが無い名前ですがEventTargetインターフェイスにはaddEventListenerメソッドが存在しているようにイベントを受け取ったり発火できる要素などに継承されています。

https://developer.mozilla.org/ja/docs/Web/API/EventTarget

ken7253ken7253

Node

NodeインターフェイスはEventTargetを継承しており、後述するElementTextなどの元となっているインターフェイスです。
(各種HTMLやSVGの要素などはこのインターフェイスを継承しています)
テキストノードという表現のしかたを耳にしたことがある人もいるかもしれませんが、それはHTML上のテキストを表現するTextがこのNodeインターフェイスを継承しているためです。

https://developer.mozilla.org/ja/docs/Web/API/Node

Window

Windowインターフェイスはその名の通りグローバルオブジェクトであるwindowの元となるインターフェイスです。
様々なHTML要素と同様にwindowもイベントを受け取ったりできますが、構造はNodeと異なるためこの階層に存在しています。

https://developer.mozilla.org/ja/docs/Web/API/Window

ken7253ken7253

Element

Elementインターフェイスはその名の通り各種要素の元となっているインターフェイスです。
このElementインターフェイスを継承するものはHTMLElementSVGElementとなっておりこのインターフェイスを境にHTMLとSVGは別のプロパティやメソッドを持つようになります。

https://developer.mozilla.org/ja/docs/Web/API/Element

ken7253ken7253

HTMLElement

HTMLElementインターフェイスはすべてのHTML要素が継承しているインターフェイスです。
例として普段良く利用している<div><a>などの要素は全てHTMLElementを継承しています。
TypeScriptを使われている方は下記のような型ガードをよく使われるかと思いますがここで使われるHTMLElementというのがまさにこのインターフェイスを表しています。

const element = document.getElementById('foo');

if (element instanceof HTMLElement) {
  // element はHTMLElementインターフェイスを継承していることが確定する
}
if (element instanceof Element) {
  /* 
   *  この場合ElementインターフェイスはHTMLとSVGの可能性があるので
   *  この中ではelementがHTML要素であることは確定しない
  */
}

https://developer.mozilla.org/ja/docs/Web/API/HTMLElement

ken7253ken7253

HTMLAnchorElement

最後に個別のHTML要素の紹介として<a>要素のインターフェイスであるHTMLAnchorElementを紹介します。
名前の通り<a>要素はHTMLAnchorElementを元にしており<a>要素が持っている各種プロパティやメソッド・イベントなどが定義されています。
基本的に各要素に対応するインターフェイスはHTML***Elementとして定義されており、一部HTMLMediaElementのようにそこからさらにHTMLAudioElementHTMLVideoElementの2つに分岐するものも存在しますが、要素とインターフェイスが1対1で対応するようになっています。

https://developer.mozilla.org/ja/docs/Web/API/HTMLAnchorElement

https://developer.mozilla.org/ja/docs/Web/API/HTMLMediaElement

ken7253ken7253

このようにHTMLやSVGの各要素は何かしらのインターフェイスを継承して作られています。

意外かもしれませんが、HTMLのコメントは
EventTarget -> CharacterData -> Commentという風に継承されているためコメントでもEventTargetのメソッドであるaddEventListenerremoveEventListenerが定義されています。

開発者ツールのコンソール画面 const comment = new Comment('Foo') undefined typeof comment.addEventListener
"function"

ken7253ken7253

何が言いたいのか

  • DOMのプロパティやメソッドには継承関係があるからそれぞれ個別に覚えるより体系を覚えたほうが効率的
  • 体系を知ると実装の違和感に気付ける
ken7253ken7253

個人的にHTMLを知る上で学びが多かったこと

  • JavaScriptでのDOM操作を学ぶ
    • DOMに関する知識がないと調べた知識を確認できない
  • Class(JavaScript)の仕組みを学ぶ
    • DOMは基本的にClassなので
    • 継承とかgetter/setterとか基礎知識がないと挙動がわからないことが多い
  • TypeScirptを触る
    • JavaScriptの世界の型はゆるゆるなのでinstanceofとか使わない
    • DOMの型が分からないと継承関係もあまり理解できない気がするので