派遣で働くエンジニアのスキルアップを応援するサイト

PRODUCED BY RECRUIT

htmxでDOMを操作するには?

サクッとわかるITトレンドでご紹介した「htmx(Hotwire)」。興味ある!という方も多かったのではないでしょうか。そこで、htmxをさらに深掘り。今回は、htmxではDOMをどのように操作するのか、またその書き方を基礎知識とあわせて解説します。

htmxとは?

Hotwire(HTML Over The Wire)と呼ばれる、JavaScriptのプログラムを書くことなくAjaxのような動作を実現する技術があります。このHotwireの動作を手軽に実現できるのが【htmxというライブラリ】です。HTMLファイルの中で読み込むだけで簡単に動きのあるウェブサイトを作ることができます。

▼htmxの詳しい解説はこちらから

htmxとDOMをあわせて学ぶ理由とは?

DOMを操作するときは一般的にJavaScriptを使います。Webブラウザに搭載されているJavaScriptエンジンは、JavaScriptが持つ処理だけでなく、Webブラウザに固有のDOM操作などについてのオブジェクトがあらかじめ用意されています。

そして、このオブジェクトに対する操作をすることで、HTMLの要素を操作できるようになっています。ただし、JavaScriptとDOMの両方を学ぶのは大変なので、本稿ではhtmxでDOMを操作する方法を解説します。

DOMを操作するには、ノードの特定方法や、可能な操作について知っておく必要があるため、以降ではそれらについても詳しく解説します。

DOMとは?
HTMLは複数の要素を組み合わせて構成されており、Webページ内の要素間の関係をまとめると以下のような木構造で表現できます。


▲『htmxで学ぶWeb技術―HTML, CSS, HTTP, DOMの基本―』P.59より引用

このように、要素間の関係を木構造で表現すると、Webブラウザで表示されたときの要素間の関係がわかりやすくなります。さらに、プログラムを使って要素を操作し、Webページの中身を動的に書き換えられます。要素の中身を変更したり、新たに要素を追加したり、既存の要素を削除したりすることで、ページの内容をリアルタイムに変化させられるのです。

これを実現するためにWebブラウザが備えるしくみとしてDOM(Document Object Model)があります。DOMでは、HTMLの要素をノードやエレメントと呼び、あるノードの上のノードを親ノード、下のノードを子ノードと呼びます。
ノードに対する処理をプログラムで実装することで、下図のようにWebブラウザ上で入力欄に入力された値をチェックしたり、表に行を追加したり、画像を入れ替えたりといった操作が可能になります。


▲『htmxで学ぶWeb技術―HTML, CSS, HTTP, DOMの基本―』P.60より引用

ノードの特定:hx-target属性

DOMを使ってノードを操作するときは、対象となるノードを特定して選択しなければなりません。このとき、ノードを特定する方法として、JavaScriptには次のような関数が用意されています。

この1番目と4番目は1つのノードだけを得ることができますが、残りはノードのリスト、つまり複数のノードの一覧を得ます。このため、得たリストをループして1つずつ取り出すなどの方法で、それぞれのノードにアクセスします。

htmxでは、こちらの記事でも登場したhx-target属性でCSSセレクタを指定します。また、拡張CSSセレクタ構文が使えるため、これらを組み合わせると上記のような特定ができます。

ノードの追加、更新、削除:hx-swap属性

ノードを特定できれば、そのノードを選択してプログラムから操作できます。たとえば、あるノードに新たな子ノードを作成し、既存のノードの配下に追加できます。また、ノードを他のノードで置き換えたり、そのノードの中身を書き換えたりできます。

もちろん、ノードの属性を変更したり、新しい属性を追加したりすることもできます。DOMからノードを削除することも基本的な操作の一部です。

htmxでノードを追加したり、更新したり、削除したりするには、hx-swapという属性を使います。このときに指定できる値として、以下のようなものがあります。


▲『htmxで学ぶWeb技術―HTML, CSS, HTTP, DOMの基本―』P.62より引用

 

div要素をクリックしたときに、contents.html の内容がdivタグの後ろに追加されるようにするには、以下のように書きます。

▼ hx_swap で追加する

<div
hx-get="contents.html" hx-swap="afterend">変更前のコンテンツ</div> 

また、クリックしたときにレスポンスにかかわらず要素を削除したい場合には、以下のように書きます。

▼ hx_swap で削除する

<div
hx-get="contents.html" hx-swap="delete">削除</div> 

デフォルトでは、その要素のinnerHTMLを使うので、要素の中身が置き換えられます。

イベントとトリガー条件の指定:hx-trigger属性

Webページは読み込まれて終わるのではなく、利用者によるWebブラウザの操作に反応して、その内容を動的に変化させたいことがあります。このような利用者の操作によって発生するものをイベントと呼びます。

ボタンであれば、クリックしたときになんらかの処理を実行したいものです。このような実行の起点になるものをトリガーといいます。標準では、それぞれの要素ごとにデフォルトのトリガー条件が決められており、htmxでは指定を省略できます。


▲『htmxで学ぶWeb技術―HTML, CSS, HTTP, DOMの基本―』P.63より引用

これとは異なる条件で動作を設定したいとき、htmxではhx-trigger属性を使って、トリガーの条件を指定します。

たとえば、マウスがその要素の上に入ったときに、「enter.html」というファイルから取得した結果を表示するdiv要素を作るには、以下のように書きます。

▼マウスが入ったときに実行

<div hx-get="enter.html" hx-trigger="mouseenter">
マウスを重ねてください
</div>

■トリガーの修飾子

トリガーは単純なものだけでなく、その動作を変更するための修飾子がいくつも用意されています。たとえば、マウスが入った最初のタイミングだけリクエストしたい場合は、hx-triggerにonceを追加します。

これによって、最初にマウスを重ねたタイミングだけリクエストが送信され、書き換えられたあとはリクエストを送信しなくなります。

▼初回だけマウスが入ったときに実行

<div hx-get="enter.html" hx-trigger="mouseenter once">
マウスを重ねてください
</div>

なお、hx-triggerに指定できるものとして、以下のようなものがあります。


▲『htmxで学ぶWeb技術―HTML, CSS, HTTP, DOMの基本―』P.64より引用

 

【もっと深堀り!】hx-triggerに指定できる処理内容の意味
 
▼delay
イベントが再度トリガーされると、カウントはリセットされます。つまり、「hx-trigger="mouseenter delay:1s"」と指定すると、マウスを1秒以内に何度も重ねるとリクエストは発行されず、最後にマウスを重ねてから1秒経ったときにリクエストが発行されます。
 
▼throttle
1回目はすぐにリクエストが発行されますが、2回目以降は指定された時間を経過しないと発行されません。

これらの属性を使うと、検索欄にキーワードの一部が入力されたときに候補を表示するなど、便利な機能を容易に実現できます。

たとえば、以下のコードのinputタグでは、キーが押されてから500ミリ秒が経過するとHTTPリクエストを発行し、その結果をresultsというidが設定されているdivタグに挿入します。

<input type="text" name="q"
    hx-get="/search"
    hx-trigger="keyup changed delay:500ms"
hx-target="#results"
placeholder="検索" >
<div id="results"></div>
【もっと深堀り!】トリガーの修飾子の複数指定と条件追加
 
なお、hx-trigger 属性にカンマ区切りで並べて指定すると、複数のトリガーを指定できます。 イベント名に続けて角括弧を使用すると、トリガーの条件を追加することもできます。
 
たとえば、以下では、div タグの上で「Control(Ctrl)」 キーを押しながらクリックしたときだけトリガーします。
<div hx-get="click.html" hx-trigger="click[ctrlKey]"> Control( Ctrl )キーを押しながらクリックしてください 。
</div>

属性の継承:hx-confirm属性

削除ボタンを押したときに、本当に削除してよいか確認するメッセージを表示したいことがあります。このように、リクエストを発行する前に確認メッセージを表示するには、hx-confirmという属性を使います。

下記のように書くと、確認メッセージを表示し、OKを押したときだけリクエストを送信します。

<button
hx-delete="/delete" hx-confirm="削除しますか?">削除</button>

htmxの属性の多くは子要素にも継承されます。つまり、属性を指定した要素だけでなく、子要素にも同じ属性が適用されます。これにより、コードの重複を避けられます。

たとえば、下記では、hx-confirm 属性をそれぞれの要素に指定しています。

<button
hx-delete="/delete" hx-confirm="削除しますか?">削除</button> 
<button
hx-put="/update" hx-confirm="更新しますか?">更新</button>

これを下記のように親要素に記述すると、HTMLの記述量を減らせます。

<div hx-confirm="よろしいですか?">
<button hx-delete="/delete">削除</button> <button hx-put="/update">更新</button>
</div>

逆に、継承したくない場合は、hx_confirmにunsetという値を設定します。下記のように書くと、削除と更新のボタンでは確認メッセージが表示されますが、キャンセルボタンを押したときは表示されません。

<div hx-confirm="よろしいですか?">
<button hx-delete="/delete">削除</button> <button hx-put="/update">更新</button> <button hx-confirm="unset" hx-get="/"> キャンセル
</button>
</div>

・・・

いかがでしたか。本格的に学ぼうとするとハードルの高いDOMですが、htmxではJavaScriptなしでも必要な操作ができることがわかりました。

まずは、htmxのようなチャレンジしやすいものからはじめて、Web技術の知識を深めていくのもいいですね。

▼htxmでのHTTPの書き方解説はこちらから

*本稿は増井敏克『htmxで学ぶWeb技術―HTML, CSS, HTTP, DOMの基本―』を再編集したものです。

【監修】増井 敏克さん
増井技術士事務所代表。技術士(情報工学部門)。情報処理技術者試験にも多数合格。ビジネス数学検定1級。「ビジネス」×「数学」×「IT」を組み合わせ、コンピュータを「正しく」「効率よく」使うためのスキルアップ支援や、各種ソフトウェアの開発、データ分析などを行う。著書に『Pythonではじめるアルゴリズム入門』『図解まるわかり プログラミングのしくみ』『「技術書」の読書術 達人が教える選び方・読み方・情報発信&共有のコツとテクニック』(翔泳社)、最新刊の『データ分析に強くなるSQLレシピ 小規模データの前処理・分析の書き方&テクニック』(インプレス)がある。

※本稿に記載されている情報は2024年5月時点のものです。

リクルートスタッフィング