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 を編集する。

Eslint Configuration

セミコロンに対するルールを追加("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 を設定してあげるとそのルールに従う。

image.png

ディレクトリ毎にルールを変えたいような場合は、ワークスペース.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
  }

下記のようにセーブ時にフォーマットが実行される。

Image from Gyazo

参考

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段階認証情報などが入っている。これがないとログインできなくなる。この子も、バックアップされないので、自分で抜き取る。

参考:Back up GitLab | GitLab

リストア

バックアップ時のGitLabと、リストア先のGitLabのバージョンは揃えておく。Dockerコンテナであっても、コンテナ内で下記を実行してあげれば、リストア可能(Dockerコマンド版もある)。

  1. バックアップファイルをリストア先のパックアップパスにおき、所有者とグループ変更する

    バックアップパスのデフォルトは /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
    
  2. データベースに接続するプロセスを停止する

     $ sudo gitlab-ctl stop puma
     $ sudo gitlab-ctl stop sidekiq
     # Verify
     $ sudo gitlab-ctl status
    
  3. リストアを実行する

     # バックアップファイルの『_gitlab_backup.tar』は不要
     $ sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce
    
  4. gitlab-secrets.jsongitlab.rb を置き換える

  5. 下記コマンドを叩いて、GitLabを更新する。

     $ sudo gitlab-ctl reconfigure
     $ sudo gitlab-ctl restart
     $ sudo gitlab-rake gitlab:check SANITIZE=true
    
  6. 最後に整合性チェックを行う

     $ sudo gitlab-rake gitlab:artifacts:check
     $ sudo gitlab-rake gitlab:lfs:check
     $ sudo gitlab-rake gitlab:uploads:check
    

参考:Restore GitLab | GitLab

バージョンアップグレード

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 ボリュームに保存されているため消えない。念の為バックアップは必須

大雑把な手順をまとめる。

  1. バックアップを取る
  2. 実行中コンテナを停止する (sudo docker stop gitlab)
  3. Dockerコンテナを削除する (sudo docker rm gitlab)
  4. 次のアップグレードパスのコンテナを立てる(sudo docker pull gitlab/gitlab-ce:<next path>参考
  5. アップグレード版GitLabが起動するのを待つ
  6. ヘルプ画面でバージョンを確認し、アップグレードできていることを確認する

あとは、所望のバージョンになるまで、2〜6を繰り返す

参考: * アップグレード * アップグレード パス

npm 概要

npm とは

npm(Node Package Manager) は、JavaScript 系のパッケージを管理するツール。インストール時に依存関係を考慮してインストールしてくれる。

OS系パッケージ管理だと、 apt, dpkg, Homebrew のようなもので、言語系パッケージとしては Rubybundler に近いものと言える。 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 の機能を(権限内で)利用できるようになる。

image.png Node.jsとはなにか?なぜみんな使っているのか? - Qiita

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 ユーザに警告する image.png
入力 window.prompt ユーザに入力させる image.png
確認 window.confirm ユーザに同意するかを選択させる image.png
印刷 window.print 印刷画面する image.png

ウィンドウ操作

メソッド名 説明
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** メソッドと、ブラウザの対応は次のとおり。

image.png

バイスピクセル比は、CSS で表す1ピクセルを、クライアント側デバイスで何ピクセルで表現するかの比率。

バイスピクセル比のイメージは次のようなもの。

image.png

例えば、デバイスピクセル比が 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ページ内の要素で何らかのイベントが発生すると、当該要素にのみイベントが発生するのではなく、その親要素にもイベントが伝搬する。

あるイベントが発生すると、次のフェーズにおいて、経路上にある要素やオブジェクトに対して、同じイベントが発生する。

  1. キャプチャリングフェーズ

    イベント発生時に、発生ノードまでDOMツリーを辿っていくフェーズ。addEventListener メソッドで設定されない限り、イベントは発生しない。

    image.png

  2. ターゲットフェーズ

    実際にイベントが発生した要素でイベントが発生するフェーズ。

    image.png

  3. バブリングフェーズ

    キャプチャリングフェーズの反対で、発生ノードから上位のノードまでDOMツリー上に辿るフェーズ。

    image.png

イベントの種類

大雑把に取得できるイベントは次のようなグループに分けられそう。

  • マウス系
  • キーボード系
  • 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>

ノードのタイプは次のようになる。

image.png

HTML の階層構造がノードの階層構造によって表現されている。

また、ノードには親子関係や兄弟関係があり、特定のノードから親ノードや子ノードを取得して操作するというようなこともある。

image.png

Document オブジェクトのメソッドを使うことで、要素やテキスト、属性といったHTMLのタグ情報を取得できる。

DOMオブジェクトの操作方法

DOMオブジェクトの基本的な操作の流れは下記を認識しておけば良さそう🧐

  1. ノードの取得

    ノードの情報へアクセスするためには、どのノードの情報が欲しいかを設定する必要があるので、まずはノードの取得をする。

    ノードの取得単位としては、タグ名や id/class/name 属性、CSSセレクタ形式を指定できる。さらに、取得したノードに対して、子・親・兄弟関係のノードを取得したり、要素ノードに絞って取得することもできる。

  2. ノード情報の取得と設定

    ノードが取得できたら当該ノードの情報、例えば『ノードのタイプ』や『ノードが持つ情報(テキストとかの値)』を参照できるようになる。

    また、ノードの情報の取得だけでなく情報自体の更新も可能。HTML文などの値を設定する時は、エスケープ処理されるのでエスケープさせたくない時には、innerHTMLouterHTML メソッドなどを利用する。

image.png

具体的なメソッドについては、かなり種類があるので、その都度必要に応じて選択していけばいいと感じた😅

ノードの作成と追加

DOMオブジェクトの操作方法では、ノードを取得し、取得したノードの情報を参照したり更新したりという話だったけど、今回は新しくDOMツリーにノードを追加する方法について。

大まかな流れは次の通り。

  1. ノードを作成する

    要素/テキスト/属性/コメント/ドキュメント断片 ノードを作成できる。

    ドキュメント断片ノードは、複数のノードをDOMに追加する時に、一時的にノードをまとめるために使用するノード。ドキュメント断片ノードに新たに追加するノードをまとめて設定しておけば、DOMに追加するときの操作が一回で済むようになる。

    イメージ的には下図のような感じで、#document-fragment ノード以下のノードを一括で調整できるようになる。ドキュメント断片ノード自体はDOM上には追加されない。

    image.png

  2. DOMツリーを更新する

    ノードを作成したら、作成したノードをDOMツリーに追加できる。ツリーへの追加は、メソッドを用いて子/親/兄弟関係の位置を指定して追加することができる。

    また、新しく追加したノードだけでなく、既存ノードについてもDOMツリーの構成を変更したりできる。例えば、次のような操作が可能。

    • 移動

      既存ノードの位置を移動する。指定されたノードは元のツリーの位置から削除され、指定した新しいツリーの位置に移動する

    • 置換

      新しくノードを作り、既存ノードと新規ノードを取り替える。

    • 削除

      既存ノードを削除する。親ではなく削除するノードを直接指定して、DOMツリーから削除する。

ノードの作成からDOMツリーの更新例は次のような感じになる。

image.png

こちらのメソッドもたくさんあるので、その時々で調べながら使っていけばいいと思いました😅

参考