htmxの「hx-on」属性でイベントハンドラを動的に設定する方法
hx-on の基本的な構文は以下の通りです。
<element hx-on="event=handler">
</element>
上記の例では、element
要素に event
イベントが発生した際に handler
関数が実行されます。
hx-on 属性で使用できるイベントは、以下の通りです。
- error
要素でエラーが発生したとき - load
要素が読み込まれたとき - submit
フォームが送信されたとき - keypress
要素のキーが押され、かつそれが有効な文字であるとき - keydown
要素のキーが押されたとき - keyup
要素のキーが離されたとき - change
要素の値が変更されたとき - blur
要素からフォーカスが外れたとき - focus
要素にフォーカスが当たったとき - dblclick
要素がダブルクリックされたとき - click
要素がクリックされたとき
hx-on 属性には、イベントハンドラ関数に加えてオプションパラメータを指定することもできます。オプションパラメータには、以下のようなものがあります。
- capture
イベントのキャプチャを有効にする - bubbles
イベントのバブリングを有効にする - stopPropagation
イベントの伝播を抑制する - preventDefault
イベントのデフォルト動作を抑制する
hx-on 属性の具体的な例をいくつかご紹介します。
- ボタンをクリックしたときにアラートを表示する
<button hx-on="click=showAlert">クリック</button>
<script>
function showAlert() {
alert("ボタンがクリックされました!");
}
</script>
- 入力フィールドに入力された値をコンソールに出力する
<input type="text" hx-on="keyup=logValue">
<script>
function logValue(event) {
console.log(event.target.value);
}
</script>
- フォームを送信したときにデータを非同期に送信する
<form hx-on="submit=submitForm">
<input type="text" name="name">
<button type="submit">送信</button>
</form>
<script>
function submitForm(event) {
event.preventDefault();
const data = new FormData(event.target);
fetch('/submit', {
method: 'POST',
body: data
})
.then(response => response.json())
.then(data => {
console.log(data);
});
}
</script>
サーバーレスの「いいね!」ボタン
この例では、hx-on 属性を使用して、ボタンをクリックしたときに非同期にいいね!数を更新するサーバーレスの「いいね!」ボタンを作成します。
<div id="like-button" hx-init="count=0" hx-get="/likes" hx-target="#like-count">
<button hx-on="click=like">いいね!</button>
<span id="like-count">0</span>
</div>
<script>
function like() {
this.disabled = true;
fetch('/likes', {
method: 'PUT'
})
.then(response => response.json())
.then(data => {
this.disabled = false;
document.getElementById('like-count').textContent = data.count;
});
}
</script>
動的なコメントフォーム
この例では、hx-on 属性を使用して、新しいコメントが送信されたときにコメントリストを動的に更新するコメントフォームを作成します。
<div id="comments">
<h2>コメント</h2>
<ul id="comment-list"></ul>
<form hx-on="submit=addComment">
<label for="comment-text">コメント:</label>
<textarea id="comment-text" name="comment"></textarea>
<button type="submit">送信</button>
</form>
</div>
<script>
function addComment(event) {
event.preventDefault();
const commentText = document.getElementById('comment-text').value;
fetch('/comments', {
method: 'POST',
body: JSON.stringify({ comment: commentText })
})
.then(response => response.json())
.then(data => {
const newComment = document.createElement('li');
newComment.textContent = data.comment;
document.getElementById('comment-list').appendChild(newComment);
document.getElementById('comment-text').value = '';
});
}
</script>
ドラッグ可能なタスクリスト
この例では、hx-on 属性を使用して、ドラッグ可能なタスクリストを作成します。
<ul id="task-list" hx-init="sortable=true">
<li hx-swap="before">タスク 1</li>
<li hx-swap="before">タスク 2</li>
<li hx-swap="before">タスク 3</li>
</ul>
<script>
document.getElementById('task-list').addEventListener('dragstart', function(event) {
event.dataTransfer.setData('text/plain', event.target.textContent);
});
document.getElementById('task-list').addEventListener('dragover', function(event) {
event.preventDefault();
});
document.getElementById('task-list').addEventListener('drop', function(event) {
const draggedItem = event.dataTransfer.getData('text/plain');
const dropTarget = event.target;
if (dropTarget !== draggedItem) {
const list = document.getElementById('task-list');
const draggedItemIndex = list.indexOf(draggedItem);
const dropTargetIndex = list.indexOf(dropTarget);
list.insertBefore(draggedItem, dropTargetIndex);
}
});
</script>
htmx に代わる選択肢として以下が挙げられます
- Alpine.js
Alpine.js は、小さな Web アプリケーションやインタラクティブな Web ページを構築するための軽量な JavaScript ライブラリです。宣言的な属性を使用して、DOM 操作、イベントハンドラ、データバインディングなどを実装することができます。 - Svelte
Svelte は、コンポーネントベースの軽量な JavaScript フレームワークです。React や Vue.js と同様に、コンポーネントベースの開発、データバインディング、ルーティングなどの機能を提供しますが、コード量が少ないのが特徴です。 - Vue.js、React.js、Angular などの JavaScript フレームワーク
これらのフレームワークは、複雑なシングルページアプリケーション (SPA) を構築するのに適しています。コンポーネントベースの開発、データバインディング、ルーティングなどの機能を提供しますが、学習曲線が比較的高くなります。 - jQuery
jQuery は、JavaScript の開発を容易にする人気のライブラリです。Ajax、イベント処理、DOM 操作などの機能を提供しており、htmx に似た構文を使用することができます。ただし、jQuery は比較的大きいため、パフォーマンスに影響を与える可能性があります。 - Vanilla JavaScript
従来の JavaScript を使用して、Ajax リクエスト、イベントハンドラ、DOM 操作などを実装することができます。この方法は、柔軟性と制御性に優れていますが、コード量が多くなり、複雑になる可能性があります。
ツール | 長所 | 短所 |
---|---|---|
htmx | シンプル、軽量、使いやすい | 機能が限られている |
Vanilla JavaScript | 柔軟性、制御性が高い | コード量が多くなる、複雑になる可能性がある |
jQuery | 使いやすい、多くのライブラリと互換性がある | 比較的大きい、パフォーマンスに影響を与える可能性がある |
JavaScript フレームワーク (Vue.js、React.js、Angular など) | 複雑な SPA の構築に適している | 学習曲線が比較的高くなる |
Svelte | 軽量、コード量が少ない | 比較的新しく、コミュニティが小さい |
Alpine.js | 軽量、使いやすい | 機能が限られている |