ブラウザの仕組を読んで
今回は、イスラエルのデベロッパーTali Garsiel という方による、ウェブブラウザのソースコードを分析・解説した内容が書かれた記事を読み、必要なところのみ抜粋します。
ブラウザの主な機能とは
選択したウェブリソース*をサーバーからリクエストして、ブラウザに表示すること。
*リソース:HTMLやPDF、画像など
※正式に「インタフェース部分にこれがあるからウェブブラウザと呼べる」という定義はないが、一般的に備わっている機能はこちら↓
- URLアドレスバー
- 戻る・進むボタン
- ブックマークのオプション
- 更新・停止ボタン
- ホームページに移動するホームボタン
これらのインターフェースをユーザーが選択して、
その先の処理をしてくれるのが次に紹介するコンポーネントたちです。
ブラウザのコンポーネントとは
インフラストラクチャ:サービスやシステムを支える基盤となる設備や要素のこと
| コンポーネント名 | 内容 | 具体例 |
|---|---|---|
| ブラウザ エンジン | UI とレンダリング エンジンの間でアクションをデータをある形式から別の形式に変換して、通信や保存ができるようにする処理をする。 | Chromium |
| レンダリング エンジン | リクエストされたコンテンツの表示を担当します。 | Blink(Chrome, Edge)、WebKit(Safari)、Gecko(Firefox) |
| ネットワーキング | HTTP リクエストなどのネットワーク呼び出しの場合、プラットフォームに依存しないインターフェースの背後で、プラットフォームごとに異なる実装を使用します。 | Chromiumのネットワークスタック |
| UI バックエンド | コンボボックスやウィンドウなどの基本的なウィジェットの描画に使用されます。このバックエンドは、プラットフォームに依存しない汎用インターフェースを公開します。内部では、オペレーティング システムのユーザー インターフェース メソッドを使用します。 | Windowsでは Win32 API、macOSでは Cocoa |
| JavaScript インタープリタ | JavaScript コードの解析と実行に使用されます。 | V8(Chrome, Edge)、SpiderMonkey(Firefox)、JavaScriptCore(Safari) |
| データ ストレージ | Cookie など、さまざまなデータをローカルに保存する必要がある場合があります。ストレージそれぞれ、Webブラウザ上でデータを保存・管理する。 | localStorage、IndexedDB、WebSQL、FileSystem等 |
レンダリングとは
リクエストされたコンテンツをブラウザの画面に表示すること
おもにレンダーツリーといった、DOMツリー(HTML)とCSSOMツリー(CSS)を組み合わせた描写する要素だけを集めたフローのことを言います。
1.HTMLの読み込みと解析
2.→DOMツリーを構築・ノードとして表現
3\→.CSSの読み込みと解析→DOMノードに適応されるスタイルを決定
4.→JavaScriptの実行→レンダーツリーの構築
5.→レイアウト→ペイント→合成
パースとは
構文解析といい、文字列として書かれたコードを構造化されたデータコードに変換すること
<html>
<body>
<h1>Hello</h1>
<p>World</p>
</body>
</html>
Webpack
パーサーを生成できるツールで、文法(構文規則)を定義することで、入力された文字列を解析し、構造化されたデータに変換するプログラムを自動的に作ってくれる便利なツール
JavaScriptで最も使われているツール
簡単に言うと、モジュール(複数のファイル)をバンドルする(1つにまとめる)ツールとなり、.sassなどもウェブ上で動かないため、Webpackを使って変換が可能になる
DOM(Document Object Model)とは
Webページの構造をプログラムから操作できるようにしたモデル
Firefox ルールツリーとは
CSSルールを効率的に管理、適応するために使うデータ構造、継承管理
pはdivの子要素となる
div > p
実際にDOM操作を書いてみる
JavaScriptでDOM開発を進める上で基本的な仕組み
- 要素ノードの取得
- 文書ツリー間の行き来
- イベントドリブンモデル
要素ノードの取得
文書ツリーから要素ノードを取り出す
例)「要素を取得して、その値を取り出す」「処理した結果を要素に反映させる」
「新規に作成した要素をある要素の配下に追加する」
getElementById(id) : idをキーにして要素を取り出すメソッド
例)現在時刻をページに反映
<span id="result"></span>
let current = new Date();
let result = document.getgetElementById('result');
result.textContent = current.toLocaleString();
//現在時刻:2022/7/17 15:17:26
querySelectorAll(class) : ノードの集合を返し反復可能なオブジェクトでfor...ofで列挙できる
let list = document.querySelectorAll('#list.external');
for(let elem of list) {
console.log(elem.href);
//https://githo.jp/df
//https://fghddd.jp/hja
| 要素取得のためのメソッド名 | 戻り値 | 概要 |
|---|---|---|
| getElementsByTagName(name) | HTMLCollection | タグ名をキーに取得 |
| getElementsByName(name) | NodeList | name属性をキーに取得(フォーム要素で利用) |
| getElementsByTagName(name) | HTMLCollection | calss属性をキーに取得 |
文書ツリー間の行き来
相対的にノードを取得する
querySelector('id')でchildrenプロパティで子要素を取得する
<form>
<label for="food">一番好きな食べ物は?:</label>
<select id="food">
<option value="ラーメン">ラーメン</option>
<option value="餃子">餃子</option>
<option value="焼肉">焼肉</option>
</select>
<input type="submit" value="送信">
</form>
let s = document.querySelector('#food');
let opts = s.children;
for(let opt of opts) {
console.log(opt.value);
}
//ラーメン
//餃子
//焼肉
イベントドリブンモデル(イベント駆動型)
- ボタンクリック
- マウスポインターが文字列上に乗った・外れた
- テキストボックスの内容が変更された
などのイベントに対して実行される
addEventListenerメソッドで実行するイベント
| 分類 | イベント名 | 発生タイミング | 要素 |
|---|---|---|---|
| 読み込み | load | ページ・画像の読み込むが完了したとき | boby・img |
| マウス | click | クリック時 | - |
| マウス | dblclick | ダブルクリックを押したとき | - |
| マウス | mousedown | マウスボタンを押したとき | - |
| マウス | mouseup | マウスボタンを離したとき | - |
| キー | keydown | キーを押したとき | - |
| フォーム | input | 内容が変化したとき | input・select |
| フォーム | change | 内容が変更し、フォーカスが外れた時 | input・select |
| フォーム | reset | リセットボタンを押したとき | form |
| フォーム | submit | サブミットボタンを押したとき | form |
| フォーカス | focus | 要素がフォーカスされたとき | - |
| 編集 | copy | コピー操作をしたとき | - |
| 編集 | cut | 切り取り操作をしたとき | - |
| その他 | scroll | スクロールしたとき | boby |
elem.addEventListener(type,listener[, opts]);
elem = 要素オブジェクト
type = イベントの種類
listener = イベントの発生時に実行するコード
opts = イベントオプション
その他
style : スタイルを操作する
elem.style.prop;
elem:要素
style:スタイルプロパティ
prop:設定値
elem.addEventListener('mouseenter', function() {
this.style.backgroundColor = 'Yellow';
}, false);
classList : スタイルクラスを適応する
this.classList.remove('hightlight')
textContent ・innerHTML : テキストを取得・設定する
result.textContent = "こんにちは、<b>太郎</b>さん!"; //こんにちは、<b>太郎</b>さん!
result.innerHTML = "こんにちは、<b>太郎</b>さん!"; //こんにちは、太郎さん!(太郎は太文字)
参考書籍
