ESLint、Prettierを使ってコード一貫性を実現する
ESLint
ESLint とは
ESLint は、コードの一貫性を高め、バグを回避することを目的としている。ECMAScript/JavaScript コードで見つかったパターンを特定し、報告してくれるツール。
JavaScript はコンパイル不要なので、typoや命名間違いなどがコンパイルエラーとして観測できず、ブラウザ上でそのまま処理されてしまう。
ESLint を用いることでそういったバグなどを事前に対処することができるようになる。
ESlint をコマンドラインで使ってみる
前提として、SSL サポートを使用してビルドされたNode.js(16.0.0以上)を整える。
CLI 実行できるようにする時には、次のコマンドを叩く。
% npm init @eslint/config ✔ How would you like to use ESLint? · problems ✔ What type of modules does your project use? · esm ✔ Which framework does your project use? · none ✔ Does your project use TypeScript? · No / Yes ✔ Where does your code run? · browser ✔ What format do you want your config file to be in? · JSON Local ESLint installation not found. The config that you've selected requires the following dependencies: eslint@latest ✔ Would you like to install them now? · No / Yes ✔ Which package manager do you want to use? · npm Installing eslint@latest added 97 packages, and audited 98 packages in 6s 24 packages are looking for funding run `npm fund` for details found 0 vulnerabilities Successfully created .eslintrc.json file in /Users/***/npm/my-app
hoge
だけを書いた test.js
を用意してコマンドを実行してみる。
% ./node_modules/.bin/eslint test.js 1:1 error 'hoge' is not defined no-undef ✖ 1 problem (1 error, 0 warnings)
リントのルールを設定したい場合は、.eslintrc.json
を編集する。
セミコロンに対するルールを追加("semi":"error"
)して、再度実行すると次のようになった。
1:1 error 'hoge' is not defined no-undef 1:5 error Missing semicolon semi ✖ 2 problems (2 errors, 0 warnings) 1 error and 0 warnings potentially fixable with the `--fix` option.
ESLint を VSCode で使ってみる
VSCode で利用する際には拡張機能を入れるだけで良さそう。.eslintrc.json
を設定してあげるとそのルールに従う。
ディレクトリ毎にルールを変えたいような場合は、ワークスペースの .vscode/settings.json
にワーキングディレクトリを設定する。
例えば、次のような構成があるとする。
root/ client/ .eslintrc.json client.js server/ .eslintignore .eslintrc.json server.js
上記に対してそれぞれLintをかけたい場合、.vscode/settingsjson
に下記を設定する。
"eslint.workingDirectories": [ "./client", "./server" ]
Prettier
Prettier とは?
Prettier はコードを一貫したスタイルに準拠させることを目的としたコードフォーマッター。バグ検出などは行わない。
Prettier をコマンドラインで使ってみる
Prettier をローカル環境で使うようにする。まずはインストール。
% npm install --save-dev --save-exact prettier added 1 package, and audited 99 packages in 450ms 25 packages are looking for funding run `npm fund` for details found 0 vulnerabilities
次に、Prettier の存在をエディタや他ファイルに知らせるために、構成ファイルを用意する。
echo {}> .prettierrc.json
Prettier とエディターがフォーマットしないファイルを認識できるように、ignore ファイルを用意する。
echo "{\n # Ignore artifacts: \n build\n coverage\n}" > .prettierignore
コードフォーマットする準備ができたので、コードフォーマットする。全てのファイルを Prettier でフォーマットする時には次のようにする。
% npx prettier --write . .eslintrc.json 22ms .prettierrc.json 1ms .vscode/settings.json 1ms package-lock.json 31ms package.json 5ms test.js 1ms
ESLint を使用する際には、互いのフォーマットルールが衝突しないように、eslint-config-prettierをインストールする。
% npm install --save-dev eslint-config-prettier
eslint-config-prettier をインストールしたら、ルールを上書きするために、ESLintの設定ファイル(.eslintrc.*)の extend
要素の最後に prettier
を追加する。
Prettier を VS Code で使ってみる
まずは、拡張機能を Prettier - Code formatter
で検索し、インストールする。
次に JavaScript に対して Prettier を規定フォーマッターにするのと、セーブ時にフォーマットを実行させるために、ワークフォルダの setting.json
に下記を追加する。
"editor.defaultFormatter": null, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true }
下記のようにセーブ時にフォーマットが実行される。
参考
GitLab-CE バックアップ、リストア、アップグレード
実行環境
項目 | 内容 |
---|---|
OS | WSL2:ubuntu2020 |
ミドルウェア | Docker-Desktop |
バックアップ
GitLabのバックアップでは、3種類のファイルをバックアップする。
GitLab
GitLab のデータ本体。コマンドは下記。
# 12.2 以上なら下のコマンドだけ $ sudo gitlab-backup create
GitLab設定ファイル(gitlab.rb)
GitLab の諸設定ファイル。IPアドレスやメール送信設定、LDAPなどをできるようにしている場合、これも移植しないと移植先で当該機能を再設定する羽目になる。
注意としては、上記のGitLabのバックアップで一緒にバックアップしてくれないので自分で抜き取る。パスは、
/etc/gitlab/gitlab.rb
。GitLab シークレットファイル(gitlab-secrets.json)
ユーザプロフィールや2段階認証情報などが入っている。これがないとログインできなくなる。この子も、バックアップされないので、自分で抜き取る。
リストア
バックアップ時のGitLabと、リストア先のGitLabのバージョンは揃えておく。Dockerコンテナであっても、コンテナ内で下記を実行してあげれば、リストア可能(Dockerコマンド版もある)。
バックアップファイルをリストア先のパックアップパスにおき、所有者とグループ変更する
バックアップパスのデフォルトは
/var/opt/gitlab/backups/
で、バックアップファイル(gitlab.rb
)に定義されているので、念の為確認する。# 例 $ sudo cp 11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar /var/opt/gitlab/backups/ $ sudo chown git:git /var/opt/gitlab/backups/11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar
データベースに接続するプロセスを停止する
$ sudo gitlab-ctl stop puma $ sudo gitlab-ctl stop sidekiq # Verify $ sudo gitlab-ctl status
リストアを実行する
# バックアップファイルの『_gitlab_backup.tar』は不要 $ sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce
gitlab-secrets.json
とgitlab.rb
を置き換える下記コマンドを叩いて、GitLabを更新する。
$ sudo gitlab-ctl reconfigure $ sudo gitlab-ctl restart $ sudo gitlab-rake gitlab:check SANITIZE=true
最後に整合性チェックを行う
$ sudo gitlab-rake gitlab:artifacts:check $ sudo gitlab-rake gitlab:lfs:check $ sudo gitlab-rake gitlab:uploads:check
バージョンアップグレード
Docker で稼働する GitLab のバージョンアップはとても簡単。コンテナの立ち上げ方はこちらを参照。
GitLab をアップグレードする際には、アップグレードパスに乗ってあげていく必要がある。本日時点では、次のようになっている。
8.11.Z-> 8.12.0-> 8.17.7-> 9.0.13-> 9.5.10-> 10.0.7-> 10.8.7-> 11.0.6-> 11.11.8-> 12.0.12-> 12.1.17-> 12.10.14-> 13.0.14-> 13.1.11-> 13.8.8-> 13.12.15-> 14.0.12-> 14.3.6-> 14.9.5-> 14.10.Z-> 15.0.Z-> 15.1.Z(複数の Web ノードを持つ GitLab インスタンスの場合) ) -> 15.4.0->最新15.Y.Z
例えば、現在のGit Labのバージョンが、14.3.2
の場合、14.3.6-> 14.9.5-> 14.10.Z-> 15.0.Z-> 15.1.Z -> 15.4.0 -> 15.Y.Z(latest)
という順に上げていく。Y,Z
は任意。
公式手順のDocker コンテナで稼働している場合は、コンテナを削除して、アップグレードパスの次のイメージをプルして、新しいコンテナを立ち上げるだけで良い。
データ自体は Docker ボリュームに保存されているため消えない。念の為バックアップは必須。
大雑把な手順をまとめる。
- バックアップを取る
- 実行中コンテナを停止する (
sudo docker stop gitlab
) - Dockerコンテナを削除する (
sudo docker rm gitlab
) - 次のアップグレードパスのコンテナを立てる(
sudo docker pull gitlab/gitlab-ce:<next path>
)参考 - アップグレード版GitLabが起動するのを待つ
- ヘルプ画面でバージョンを確認し、アップグレードできていることを確認する
あとは、所望のバージョンになるまで、2〜6を繰り返す
参考: * アップグレード * アップグレード パス
npm 概要
npm とは
npm(Node Package Manager) は、JavaScript 系のパッケージを管理するツール。インストール時に依存関係を考慮してインストールしてくれる。
OS系パッケージ管理だと、 apt
, dpkg
, Homebrew
のようなもので、言語系パッケージとしては Ruby の bundler
に近いものと言える。 bundler
自体は パッケージ管理用の gem
(パッケージ)らしいので微妙に違う🧐
npm パッケージを集めたリポジトリには、40万を超えるパッケージが登録されているらしい。
npm を使ってみる
まずは、簡単にコマンドを知るところから。
- パッケージの検索
% npm search <パッケージ名>
- パッケージのインストール
% npm install <パッケージ名> # package.json に記録する % npm install <パッケージ名> --save
package.json
に書かれたパッケージは、当該ファイルがある場所で npm install
を叩くと、ファイル内に書かれたパッケージを再度インストールできる。
-g
オプションをつけると、システムファイルディレクトリにインストールされる。
- パッケージのアップデート
% npm update <パッケージ名> # パッケージ名を省略すると、package.json に書かれたパッケージ全てをアップデート % npm update
- パッケージのアンインストール
% npm uninstall <パッケージ名> % npm rm <パッケージ名> # 省略版 # アンインストール結果を package.json に記録する % npm uninstall --save
試しに、emoji
パッケージをインストールする。
% npm install -g emoj # <= インストール npm WARN ERESOLVE overriding peer dependency added 244 packages, and audited 245 packages in 22s 37 packages are looking for funding run `npm fund` for details found 0 vulnerabilities % source ~/.zshrc # <= パス更新 % emoj # <= 対話インターフェース起動 › unicorn 🦄 🌈 🦄 has been copied to the clipboard % 🦄 # <= コピぺできる zsh: command not found: 🦄 % emoj 'unicorn' # <= コマンド式 🦄 🌈 % npm uninstall -g emoj # <= アンインストール % source ~/.zshrc # <= パス更新
参考
nvm と Node.js を使ってみる
nvm って?
nvm(Node Version Manager) は Node.js のバージョンマネージャ。コマンドラインにて異なるバージョンの node を使えるようにできる。node については後述。
下記のような感じで、コマンドライン上で node の切り替えやインストールなどができるようになる。
$ nvm use 16 Now using node v16.9.1 (npm v7.21.1) $ node -v v16.9.1 $ nvm use 14 Now using node v14.18.0 (npm v6.14.15) $ node -v v14.18.0 $ nvm install 12 Now using node v12.22.6 (npm v6.14.5) $ node -v v12.22.6
nvm インストール
brew を使って nvm をインストール
% brew install nvm
nvm — Homebrew マニュアルに従い、下記を実行する。
% mkdir ~/.nvm
パスを追加するために、.zshrc
に下記を追加する
export NVM_DIR="$HOME/.nvm" [ -s "$(brew --prefix)/opt/nvm/nvm.sh" ] && \. "$(brew --prefix)/opt/nvm/nvm.sh" # This loads nvm [ -s "$(brew --prefix)/opt/nvm/etc/bash_completion.d/nvm" ] && \. "$(brew --prefix)/opt/nvm/etc/bash_completion.d/nvm" # This loads nvm bash_completion
次にパスを更新するために下記を実行する。
% source ~/.zshrc % nvm -v 0.39.2 # <= nvm のバージョンが表示される
Node.js って?
Node.js は Web サーバでもなければ Rails のような Web フレームワークでもなく、JavaScript の実行環境。
JavaScript 単体では Web ブラウザ上でしか機能しないが、Node.js を用いることで、それが動作する OS の機能を(権限内で)利用できるようになる。
nvm で Node.js をインストールする
Node.js には長期サポートバージョンがあるので、それをインストールする。下記は長期サポートの最新版をインストールする際のコマンド。
% nvm install --lts % nvm ls -> v18.12.1 system default -> lts/* (-> v18.12.1) iojs -> N/A (default) unstable -> N/A (default) node -> stable (-> v18.12.1) (default) stable -> 18.12 (-> v18.12.1) (default) lts/* -> lts/hydrogen (-> v18.12.1) lts/argon -> v4.9.1 (-> N/A) lts/boron -> v6.17.1 (-> N/A) lts/carbon -> v8.17.0 (-> N/A) lts/dubnium -> v10.24.1 (-> N/A) lts/erbium -> v12.22.12 (-> N/A) lts/fermium -> v14.21.1 (-> N/A) lts/gallium -> v16.18.1 (-> N/A) lts/hydrogen -> v18.12.1
最後に、~/.zshrc
に下記を追加する。
# place this after nvm initialization! autoload -U add-zsh-hook load-nvmrc() { local nvmrc_path="$(nvm_find_nvmrc)" if [ -n "$nvmrc_path" ]; then local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")") if [ "$nvmrc_node_version" = "N/A" ]; then nvm install elif [ "$nvmrc_node_version" != "$(nvm version)" ]; then nvm use fi elif [ -n "$(PWD=$OLDPWD nvm_find_nvmrc)" ] && [ "$(nvm version)" != "$(nvm version default)" ]; then echo "Reverting to nvm default version" nvm use default fi } add-zsh-hook chpwd load-nvmrc load-nvmrc
上記をすると、.nvmrc
ファイルのあるディレクトリに入ると、自動的に nvm use
を呼び出すようになる。つまり、当該プロジェクトが動く Node.js のバージョンを判断して起動してくれるようになる。
参考
JavaScript入門〜ブラウザ操作とフォーム〜
JavaScript でブラウザ操作
JavaScript では色々ブラウザに対して操作できる。
ダイアログ表示
ダイアログ名 | メソッド名 | 説明 | サンプル |
---|---|---|---|
警告 | window.alert |
ユーザに警告する | ![]() |
入力 | window.prompt |
ユーザに入力させる | ![]() |
確認 | window.confirm |
ユーザに同意するかを選択させる | ![]() |
印刷 | window.print |
印刷画面する | ![]() |
ウィンドウ操作
メソッド名 | 説明 |
---|---|
window.open |
新しいタブもしくはウィンドウで指定したURLを開く。第二引数を設定すると新規ウィンドウで開く。 |
window.close |
window.open メソッドで開いたページを閉じる |
自動実行
分類 | メソッド名 | 説明 |
---|---|---|
時間指定 | window.setTimeout |
指定時間後に実行する |
繰り返し | window.setInterval |
一定時間毎に実行する |
タイマーをキャンセルすることもできる。
ウィンドウ表示
メソッド名 | 説明 |
---|---|
window.outerWidth |
ブラウザの幅の取得 |
window.outerHeight |
ブラウザの高さの取得 |
window.innerWidth |
コンテンツ表示領域の幅の取得 |
window.innerHeight |
コンテンツ表示領域の高さの取得 |
window.devicePixelRatio |
デバイスピクセル比の取得 |
window.resizeTo |
絶対指定でサイズ変更 |
window.resizeBy |
相対指定でサイズ変更 |
outer**
メソッド, inner**
メソッドと、ブラウザの対応は次のとおり。
デバイスピクセル比は、CSS で表す1ピクセルを、クライアント側デバイスで何ピクセルで表現するかの比率。
例えば、デバイスピクセル比が 2 の場合に CSS ピクセルサイズが 200 ✖️ 200 の画像を綺麗に表示するためには、400 ✖️ 400 の画像を用意する必要がある。
ページのURL情報参照
プロパティ名 | 説明 |
---|---|
location.href |
説明 |
location.protocol |
プロトコル |
location.host |
ホスト名(ポート番号含む) |
location.hostname |
ホスト名 |
location.port |
ポート番号(URLに明示的な場合のみ) |
location.pathname |
パス部分 |
location.search |
クエリ文字列 |
location.hash |
アンカー部分 |
ページを移動・更新する
メソッド名 | 説明 |
---|---|
location.assign |
指定した URL を読み込み表示する。履歴を残すため『戻る』が使える |
location.replace |
指定した URL を読み込み表示する。履歴を残さないため『戻る』が使えない |
location.reload |
現在のページを再読み込みする |
history.back |
ブラウザの履歴を一つ戻る |
history.forward |
ブラウザの履歴を一つ進める |
history.go |
引数に指定した分だけ履歴を進める。負の場合もどる |
指定したURLを読み込み表示するのは、location.href
プロパティに URL を代入する方法でも実行でき、その場合は履歴を残すため『戻る』が使える。
JavaScript でフォームを操作する
JavaScript ではHTML のフォーム要素の情報を取得したり、更新したりできる。
フォーム要素の値を取得する際には、 HTMLInputElement オブジェクトのプロパティで指定する。
プロパティ名 | 取得できる HTML 要素 |
---|---|
element.value |
テキストボックス、テキストエリア、ドロップダウン、スライダー、カラーピッカー、ファイル選択 |
element.checked |
チェックボックス、ラジオボタン |
element.files |
複数ファイル選択 |
参考
JavaScript入門〜イベント処理〜
イベント処理とは
JavaScript では、Webページ上でイベントが発生したときにあらかじめ登録しておいた処理を実行させられる。イベント発生時に実行される処理や関数をイベントハンドラと呼ぶ。
イベントには、Webページ上でのマウス操作、キーボード操作、Webページ読み込み完了などがある。イベントの一覧は、HTML Standardにまとめられている。
イベントハンドラーの登録
イベントハンドラーの登録には、大きく2つの方法がある。
DOMで取得した要素のプロパティに登録する
下のように、DOMで要素ノードを取得し、取得したノードのプロパティに、イベントハンドラを設定する。イベントハンドラを無名関数やアロー関数を使って書くことも可能。
<input type="button" value="button" id="xxx">
<script>
let button = document.getElementById('xxx');
button.プロパティ = イベントハンドラ;
</script>
addEventListner
メソッドでイベントリスナーを登録する上記メソッドを用いてイベントに対して登録した関数をイベントリスナーと呼ぶ。
<input type="button" value="button" id="xxx">
<script>
let button = document.getElementById('xxx');
button.addEventListener = ('click', コールバック関数);
</script>
DOM要素のプロパティに登録する場合との違いは、プロパティの方のコールバックは1つしか登録できないが、addEventListner
では複数のイベントリスナーを登録できる。
イベントが発生すると、登録した順にイベントリスナーが呼ばれる。
<input type="button" value="button" id="xxx">
<script>
function dispHello(){
console.log('Hello');
}
function dispBye(){
console.log('Bye');
}
let button = document.getElementById('xxx');
button.addEventListener('click', dispHello);
button.addEventListener('click', dispBye);
</script>
HTML要素の属性として登録する方法もあるが、推奨されていない方法なので、詳細は割愛。コード的には、次のようなもの。
<input type="button" value="button" onclick="console.log('Hello')">
イベントハンドラの記述位置
HTMLからDOMツリーを構築するとき、HTMLの先頭から解析していくが、script
タグがあると解析を中断して、JavaScript を実行しようとする。
DOMツリーは完成していない状態のため、script
タグ内から未定義の属性を参照しようとすると実行エラーを起こす。
よって、JavaScript のコードを書く時には次のことに気をつける。
JavaScript のコードを HTML ページの末尾に記述する
最後(
</bod>
の直前)に書いておけば、DOMツリーは出来上がっているので問題にならないDOMContentLoaded イベントを利用する
DOMContentLoaded イベントは、DOMツリーが完成した時に発生するイベント。イベントリスナー登録で、このイベントを指定することで、DOMツリーが完成した後に登録されるようになる。
<script>
document.addEventListener('DOMContentLoaded', function(){
let button = document.getElementById('xxx');
button.addEventListener('click', function(){
console.log('Thank you');
});
});
</script>
load イベントを利用する
DOMツリー完了後にDOMContentLoaded イベントが発生する。その後、画像やスタイルシート等の全リソース読み込みが完了すると、load イベントが発生する。
イベントリスナーではなく、要素ノードのプロパティとしてイベントハンドラを登録する時に、次のようにして利用することができる。
<script>
window.onload = function(){
let button = document.getElementById('xxx');
button.onclick = function(){
console.log('How are you?');
};
};
</script>
script タグで defer 属性を設置する
script タグにて外部ファイル読み込み時にのみ利用できる。 defer 属性が設定された script タグでは、すぐに実行されるのではなく、DOMツリー構築後の DOMContentLoaded イベントが発生する直前に実行される。
イベントを受け取る
イベントハンドラやイベントリスナーが呼び出された時、そのトリガとなったイベントを引数で受け取ることができる。
受け取れる情報は、Event - Web API | MDNにまとめられている。書き方として、次のような形。
<input type="button" value="button" id="xxx"> <script> let button = document.getElementById('xxx'); button.addEventListener('click', function(event){ console.log('type :' + event.type); //=> click }); </script>
イベントの伝搬
HTMLページ内の要素で何らかのイベントが発生すると、当該要素にのみイベントが発生するのではなく、その親要素にもイベントが伝搬する。
あるイベントが発生すると、次のフェーズにおいて、経路上にある要素やオブジェクトに対して、同じイベントが発生する。
キャプチャリングフェーズ
イベント発生時に、発生ノードまでDOMツリーを辿っていくフェーズ。addEventListener メソッドで設定されない限り、イベントは発生しない。
ターゲットフェーズ
実際にイベントが発生した要素でイベントが発生するフェーズ。
バブリングフェーズ
キャプチャリングフェーズの反対で、発生ノードから上位のノードまでDOMツリー上に辿るフェーズ。
イベントの種類
大雑把に取得できるイベントは次のようなグループに分けられそう。
- マウス系
- キーボード系
change
イベントinput
イベント- コピペ系
- データ読み込み系
- その他
マウス系
マウス系はマウス操作に関するイベントで、次のように細分化できる。
- クリック
- ダブルクリック
- ボタンを立ち下げ時
- ボタンを立ち上げ時
- マウスが要素上を移動した時
- マウスが要素上に来た時
- マウスが要素上から離れた時
クリック、ボタン立ち下げ、ボタン立ち上げは、よく似た状態だが、イベントとしては『立ち下げ⇨立ち上げ⇨クリック』の流れで発生する。
クリック間隔が短い時は、連続した動作として認識され、連続回数が計算される。よって、ダブルクリックもクリックを短い間隔で実行した時に認識される。
その他にも、MouseEvent
オブジェクトではイベント発生時のマウス座標や、キー情報(Alt
, Ctrl
, Meta
, Shift
)も参照できる。
キーボード系
キーボード系はキーボード操作に関するイベントで、次のように細分化できる。
- キーを押している時
- キーを離した時
キーを押したままの状態にすると、イベントも連続して発生し続ける。その場合、KeyboardEvent.repeat
プロパティが true
になる。
キー立ち下げ時のみにしたい場合には、次のようなコードにする。
<textarea id="memo"></textarea> <script> function keyDown(event){ if (!event.repeat){ console.log('KeyDown code:' + event.code); } } let textarea = document.getElementById('memo'); textarea.addEventListener('keydown', keyDown); </script>
KeyboardEvent
オブジェクトでは、押されたキーやキーの文字などを参照するためのプロパティが用意されている。
change イベント
change
イベントは、上記がユーザ操作によって変更が確定されたときに発生する。
change
イベントはさらに次のように細分化できる。
- フォーム(
input
要素) - 選択メニュー(
select
要素) - テキストエリア(
textarea
要素)
input イベント
change
イベントに似ているが、input
イベントでは入力の度にイベントが発生する。
input
イベントはさらに次のように細分化できる。
- フォーム(
input
要素) - 選択メニュー(
select
要素) - テキストエリア(
textarea
要素)
また、InputEvent
オブジェクトでは入力された文字の値を逐次取得できる。
コピペ系
コピペ系は、要素でコピペ操作をした時に発生するイベントで、次のイベントに細分化できる。
copy
イベントpaste
イベントcut
イベント
それぞれイベントが設定されている要素ノードに上で、コピペ操作を行うとイベントが発生する。
データ読み込み系
データ読み込み系は文字通り、データ読み込みに関するイベントで、次のように細分化できる。
- ページ読み込み完了時(全リソース読み込み完了)
- DOMツリー構築完了時
ページ読み込みとDOMツリー構築では、DOMツリー構築の方が先に完了するため、イベントの呼び出し順は『DOMツリー構築完了⇨ページ読み込み完了』となっている。
HTMLページに含まれる要素に対しての処理は、DOMツリー構築完了時で良いが、画像に関する処理などはページ読み込み完了時が適切。
その他
そのほかにも次のイベントがある。
- 現在ページから他ページに遷移される直前
- ウィンドウサイズが変更される時
参考
JavaScript入門〜DOMとは〜
DOMとは
DOM (Document Object Model) は HTML や XML 文書を取り扱うための API 。
DOM では、ドキュメントに含まれる要素やテキストデータをオブジェクトとして扱い、ドキュメントはオブジェクトが階層的に組み合わせられたものと識別する。
DOM ではドキュメントを構成するオブジェクトのことをノードと呼び、ノードは大まかに要素ノード、テキストノード、属性ノードの3タイプがある。
例えば、次のような HTML があるとする。
<!DOCTYPE HTML> <html> <head> <title>散歩</title> </head> <body> <p id="xxx"> 今日は<strong>「イラスト入門」</strong>を購入 </p> </body> </html>
ノードのタイプは次のようになる。
HTML の階層構造がノードの階層構造によって表現されている。
また、ノードには親子関係や兄弟関係があり、特定のノードから親ノードや子ノードを取得して操作するというようなこともある。
Document オブジェクトのメソッドを使うことで、要素やテキスト、属性といったHTMLのタグ情報を取得できる。
DOMオブジェクトの操作方法
DOMオブジェクトの基本的な操作の流れは下記を認識しておけば良さそう🧐
ノードの取得
ノードの情報へアクセスするためには、どのノードの情報が欲しいかを設定する必要があるので、まずはノードの取得をする。
ノードの取得単位としては、タグ名や
id/class/name
属性、CSSセレクタ形式を指定できる。さらに、取得したノードに対して、子・親・兄弟関係のノードを取得したり、要素ノードに絞って取得することもできる。ノード情報の取得と設定
ノードが取得できたら当該ノードの情報、例えば『ノードのタイプ』や『ノードが持つ情報(テキストとかの値)』を参照できるようになる。
また、ノードの情報の取得だけでなく情報自体の更新も可能。HTML文などの値を設定する時は、エスケープ処理されるのでエスケープさせたくない時には、
innerHTML
やouterHTML
メソッドなどを利用する。
具体的なメソッドについては、かなり種類があるので、その都度必要に応じて選択していけばいいと感じた😅
ノードの作成と追加
DOMオブジェクトの操作方法では、ノードを取得し、取得したノードの情報を参照したり更新したりという話だったけど、今回は新しくDOMツリーにノードを追加する方法について。
大まかな流れは次の通り。
ノードを作成する
要素/テキスト/属性/コメント/ドキュメント断片 ノードを作成できる。
ドキュメント断片ノードは、複数のノードをDOMに追加する時に、一時的にノードをまとめるために使用するノード。ドキュメント断片ノードに新たに追加するノードをまとめて設定しておけば、DOMに追加するときの操作が一回で済むようになる。
イメージ的には下図のような感じで、
#document-fragment
ノード以下のノードを一括で調整できるようになる。ドキュメント断片ノード自体はDOM上には追加されない。DOMツリーを更新する
ノードを作成したら、作成したノードをDOMツリーに追加できる。ツリーへの追加は、メソッドを用いて子/親/兄弟関係の位置を指定して追加することができる。
また、新しく追加したノードだけでなく、既存ノードについてもDOMツリーの構成を変更したりできる。例えば、次のような操作が可能。
移動
既存ノードの位置を移動する。指定されたノードは元のツリーの位置から削除され、指定した新しいツリーの位置に移動する
置換
新しくノードを作り、既存ノードと新規ノードを取り替える。
削除
既存ノードを削除する。親ではなく削除するノードを直接指定して、DOMツリーから削除する。
ノードの作成からDOMツリーの更新例は次のような感じになる。
こちらのメソッドもたくさんあるので、その時々で調べながら使っていけばいいと思いました😅