## Le cœur de HTMX : les déclencheurs et les techniques de contrôle avancées {#sec-f4f92dc347e1} Dans les articles précédents, nous avons exploré les méthodes de base pour envoyer des requêtes au serveur avec [[HTMX]]. Nous avons constaté qu'en utilisant des attributs comme `hx-get`, `hx-post`, `hx-put` et `hx-delete`, il est possible d'implémenter un grand nombre d'opérations Ajax sans avoir recours à la fonction `fetch()` de JavaScript. Cependant, en utilisant HTMX, on souhaite souvent contrôler **non pas tant l'envoi de la requête que le moment où elle est envoyée**. C'est là qu'intervient `hx-trigger`. Si `hx-get` ou `hx-post` définissent **« ce qu'il faut faire »**, `hx-trigger` détermine **« quand le faire »**. Sans `hx-trigger`, HTMX pourrait sembler être un simple outil Ajax qui envoie des requêtes uniquement lors d'un clic sur un bouton. Mais c'est avec l'utilisation de `hx-trigger` que la satisfaction d'utiliser HTMX commence vraiment à monter. Par exemple, les actions suivantes deviennent possibles sans une seule ligne de code JavaScript : - Envoyer une requête de recherche uniquement après l'arrêt de la saisie. - Empêcher les clics multiples en peu de temps. - Actualiser automatiquement à intervalles réguliers. - Charger un élément uniquement lorsqu'il apparaît à l'écran. - Envoyer une requête uniquement sous certaines conditions. - Ajuster la priorité pour éviter les conflits entre différentes requêtes. Au début, je me disais : « Pourquoi utiliser [[HTMX]] quand quelques lignes de `fetch` suffiraient ? » et je ne voyais HTMX que comme un simple outil Ajax. Mais après avoir expérimenté les puissantes capacités de contrôle de `hx-trigger`, mon attitude a complètement changé. Dans cet article, nous allons passer en revue les **déclencheurs et les techniques de contrôle avancées**, qui peuvent être considérés comme le véritable cœur de HTMX. ![Image conceptuelle des déclencheurs et des techniques de contrôle avancées de HTMX](/media/whitedec/blog_img/a594fadd13f94a14a89f10cd1ba0bafe.webp) --- ## [[HTMX]] n'est pas qu'un simple outil pour boutons {#sec-31cdd005939f} Lorsque l'on découvre HTMX, on commence généralement par un exemple comme celui-ci : ```html
``` À première vue, HTMX peut sembler être un simple « outil qui envoie des requêtes Ajax quand on clique sur un bouton ». Bien sûr, c'est déjà très pratique. Mais ce n'est qu'une partie de ce que HTMX peut faire. Ce qui est vraiment important, c'est la capacité de **déclarer le moment et les conditions de déclenchement de la requête directement en HTML**. Par exemple : - Envoyer une requête au serveur à chaque frappe dans une barre de recherche est une très mauvaise expérience utilisateur. Par contre, si la requête n'est envoyée que 500 ms après l'arrêt de la saisie, l'expérience sera bien plus fluide. - Certains boutons peuvent être conçus pour ne fonctionner que si l'on clique dessus **tout en maintenant la touche Ctrl enfoncée**. - Ou encore, on peut souhaiter charger des données uniquement lorsqu'un élément spécifique devient visible à l'écran après un défilement. Si vous deviez écrire du JavaScript à chaque fois pour gérer ces situations, votre code grossirait rapidement. En revanche, HTMX permet d'exprimer une grande partie de ce contrôle **en combinant des attributs, sans une seule ligne de JavaScript**. C'est vraiment étonnant. Le choc que j'ai ressenti en découvrant `hx-trigger` de HTMX est comparable à celui d'un développeur C++ découvrant le code Python et se disant : « Quoi ? Pas de déclaration de type ?? ». --- ## Déclencheurs de base : click, change, submit {#sec-a730147be101} La première chose à savoir est que [[HTMX]] est conçu pour bien s'intégrer aux comportements HTML par défaut. Par exemple, un bouton est naturellement associé à l'événement `click`, Un formulaire à l'événement `submit`, Et un élément de saisie aux événements comme `change` selon le contexte. ```html ``` Ce bouton envoie une requête au clic, sans qu'il soit nécessaire d'ajouter explicitement `hx-trigger="click"`. Il en va de même pour les formulaires : ```html
``` Dans ce cas, la requête est déclenchée lors de la soumission du formulaire. En d'autres termes, HTMX fonctionne de manière assez intelligente pour les scénarios très basiques. Mais c'est à partir de là que notre intérêt doit se porter. **Déclarer directement les moments et les conditions souhaitées, au-delà des valeurs par défaut.** C'est précisément ce que nous voulons faire. --- ## Événements standards couramment utilisés avec `hx-trigger` vs déclencheurs spécifiques à [[HTMX]] {#sec-8354ed76dc75} Il est essentiel de maîtriser le tableau ci-dessous. Le point clé est que **les événements DOM standards fournis par le navigateur sont bien sûr utilisables, et il existe en plus quelques déclencheurs spécifiques à HTMX**. | Catégorie | Valeur | Signification | Situations fréquentes | Exemple | | ---------- | ----------------- | ---------------------------- | ----------------------------------- | ---------------------------------------------------------------------- | | Événement standard | `click` | Requête au clic | Boutons, liens, exécution d'actions | `hx-trigger="click"` | | Événement standard | `input` | Requête à chaque modification de la valeur d'entrée | Recherche en temps réel, auto-complétion | `hx-trigger="input changed delay:500ms"` | | Événement standard | `change` | Requête lorsque la valeur est confirmée et modifiée | `select`, `checkbox`, saisie après blur | `hx-trigger="change"` | | Événement standard | `submit` | Requête à la soumission du formulaire | Soumission de formulaire | `hx-trigger="submit"` | | Événement standard | `keyup` | Requête au relâchement d'une touche | Recherche basée sur la frappe, réactions rapides | `hx-trigger="keyup delay:500ms"` | | Événement standard | `keydown` | Requête à l'appui d'une touche | Raccourcis clavier, interactions au clavier | `hx-trigger="keydown[from:body]"` | | Événement standard | `mouseup` | Requête au relâchement du bouton de la souris | Réaction après glisser/sélection | `hx-trigger="mouseup"` | | Spécifique à htmx | `load` | Requête dès le chargement de l'élément | Chargement différé, remplissage de données initiales | `hx-trigger="load"` | | Spécifique à htmx | `revealed` | Requête lorsque l'élément apparaît à l'écran | Défilement infini, lazy loading | `hx-trigger="revealed"` | | Spécifique à htmx | `intersect` | Requête lorsque l'élément croise la fenêtre d'affichage | Lazy loading plus précis, chargement basé sur le défilement | `hx-trigger="intersect once"` | | Syntaxe htmx spécifique | `every 5s` | Requête à intervalles réguliers | Polling, mise à jour de l'état | `hx-trigger="every 5s"` | | Événement personnalisé | `my-custom-event` | Requête avec un événement défini par l'utilisateur | En-têtes de serveur, intégration JS, architecture d'événements souple | `hx-trigger="itemSaved from:body"` | | Modificateur | `delay:500ms` | Requête uniquement s'il n'y a pas d'événement supplémentaire pendant le temps spécifié | Débouncing, optimisation de la recherche en temps réel | `hx-trigger="keyup delay:500ms"` | | Modificateur | `throttle:1s` | Limite les requêtes répétées sur une courte période | Prévention des clics multiples, suppression des requêtes excessives | `hx-trigger="click throttle:1s"` | | Modificateur | `once` | Limite le déclenchement à une seule fois | Chargement initial, événement unique | `hx-trigger="intersect once"` | | Modificateur | `changed` | Requête uniquement si la valeur a réellement changé | Optimisation des champs de saisie, prévention des requêtes inutiles | `hx-trigger="input changed delay:500ms"` | | Modificateur | `from:body` | Spécifie une autre cible pour la détection de l'événement | Réception d'événements globaux, traitement d'événements personnalisés | `hx-trigger="itemSaved from:body"` | | Modificateur | `[condition]` | Requête uniquement si la condition est remplie | Combinaisons de touches auxiliaires, condition de longueur de saisie | `hx-trigger="click[ctrlKey]"` / `hx-trigger="keyup[value.length > 1]"` | | Modificateur | `consume` | Empêche la propagation de l'événement aux éléments parents ou supérieurs | Prévention des conflits de requêtes htmx imbriquées | `hx-trigger="click consume"` | | Modificateur | `queue:first` | Lors de la mise en file d'attente de nouveaux événements, ne conserve que le premier | Maintenir uniquement la première requête lors de saisies continues | `hx-trigger="input queue:first"` | | Modificateur | `queue:last` | Lors de la mise en file d'attente de nouveaux événements, ne conserve que le dernier | Barre de recherche, auto-complétion | `hx-trigger="input queue:last"` | | Modificateur | `queue:all` | Conserve tous les événements en file d'attente | Lorsque tous les événements doivent être traités séquentiellement | `hx-trigger="input queue:all"` | | Modificateur | `queue:none` | Ignore les nouveaux événements si une requête est en cours | Blocage complet des requêtes en double | `hx-trigger="click queue:none"` | La valeur de `hx-trigger` commence généralement par un **événement**, puis, si nécessaire, des **filtres** et des **modificateurs** sont ajoutés pour la combiner. Autrement dit, on peut la lire dans l'ordre suivant : **« quand quelque chose se produit (événement), sous quelles conditions (filtre), et de quelle manière (modificateur) »**. La forme est généralement `event[filter] modifier modifier`. ```html ``` - `keyup` → Au relâchement d'une touche - `[value.length > 1]` → Uniquement si la valeur de saisie est supérieure à 1 caractère - `changed delay:500ms` → Requête uniquement si la valeur a changé et qu'il n'y a pas eu de saisie supplémentaire pendant 0,5 seconde ## Quelques exemples utiles {#sec-d893c37bc6f7} Bien que le tableau ci-dessus résume les informations, il serait dommage de s'arrêter là. Je vais vous montrer quelques-uns de mes exemples de déclencheurs préférés. ### Envoyer une requête uniquement après l'arrêt de la saisie : `delay` {#sec-cd31c7256394} Lors de la création de fonctionnalités telles que l'auto-complétion de la barre de recherche ou le filtrage en temps réel, l'envoi d'une requête à chaque frappe de l'utilisateur peut surcharger le serveur et rendre l'expérience utilisateur quelque peu précipitée. Dans ces cas, l'utilisation de `delay` rend l'expérience beaucoup plus fluide. ```html
``` Ce code n'envoie pas de requête immédiatement à chaque frappe de l'utilisateur. Au lieu de cela, il envoie une requête **500 ms après l'arrêt de la saisie**. C'est en fait du **débouncing**. Pour l'implémenter en JavaScript, il faudrait du code pour gérer un minuteur, annuler le minuteur précédent et en définir un nouveau. Mais avec [[HTMX]], c'est réglé avec un simple attribut. Cette fonctionnalité est presque indispensable pour les interfaces utilisateur de recherche, de suggestion automatique et de filtrage. --- ### Éviter les envois trop fréquents : `throttle` {#sec-c84ae134ee88} Si `delay` donne l'impression d'« attendre un instant après l'arrêt de la saisie avant d'envoyer », `throttle` est plus axé sur la « limitation des envois trop fréquents sur une courte période ». ```html ``` Dans ce cas, même si l'utilisateur clique très rapidement plusieurs fois sur le bouton, vous pouvez contrôler que les requêtes ne soient pas envoyées de manière excessive et consécutive en moins d'une seconde. C'est très utile dans les situations suivantes : - Prévention des clics multiples - Blocage des requêtes répétées trop rapides - Réduction de la charge du serveur - Prévention de l'exécution accidentelle de la même action plusieurs fois C'est particulièrement pertinent pour des boutons comme « J'aime », « Enregistrer », « Actualiser » ou « Synchroniser ». --- ### Requêtes automatiques à intervalles réguliers : `every` {#sec-0195e4e0d263} En utilisant [[HTMX]], la fonctionnalité `every` est étonnamment attrayante. Lorsque vous souhaitez actualiser une zone spécifique du serveur à intervalles réguliers, vous n'avez pas besoin d'écrire une logique de polling distincte en JavaScript. ```html
서버 상태를 불러오는 중...
``` Ce code envoie une requête GET à `/server-status/` toutes les 5 secondes et met à jour l'élément lui-même avec la réponse. Les cas d'utilisation sont plus nombreux qu'on ne le pense : - Surveillance de l'état du serveur - Affichage de la progression des tâches - Mise à jour des chiffres du tableau de bord - Mise à jour du nombre de notifications de chat - Affichage d'informations simples en temps réel sur un écran d'administration Bien sûr, il faut faire attention à ne pas en abuser avec des intervalles trop courts, car cela pourrait surcharger le serveur. Mais utilisée à bon escient, la capacité de résoudre une telle fonctionnalité avec de simples attributs HTML est l'un des charmes de HTMX. --- ### Activer uniquement sous certaines conditions : le filtrage d'événements {#sec-c5a0b8688eb1} La fonctionnalité de filtrage d'événements est vraiment excellente. Lorsque je l'ai découverte pour la première fois, j'ai ressenti une grande gratitude envers les développeurs et contributeurs de [[HTMX]]. C'est formidable. Avec HTMX, vous pouvez ajouter des conditions après un événement pour **restreindre les requêtes à des situations spécifiques**. ```html ``` Ce code ne fonctionnera pas avec un simple clic. La requête de suppression ne sera déclenchée **que si vous cliquez en maintenant la touche Ctrl enfoncée**. Ce type de déclencheur conditionnel est un petit détail qui peut rendre l'expérience utilisateur beaucoup plus raffinée. Par exemple : - Exécuter uniquement lorsqu'une touche auxiliaire spécifique est enfoncée - Exécuter uniquement si une case à cocher est sélectionnée - Rechercher uniquement si la valeur de saisie dépasse une certaine longueur - Ne pas envoyer de requête si la chaîne est vide Peut être étendu à des flux similaires. ```html ``` De cette façon, vous pouvez faire en sorte que la requête ne soit envoyée que si le terme de recherche contient au moins deux caractères. --- ### `load` : Exécuter dès le chargement de la page ou de l'élément {#sec-066488ddc1d7} Il arrive que l'on veuille remplir certaines zones de données dès l'ouverture de la page. Par exemple, les statistiques du tableau de bord, les listes de recommandations ou les zones de notification. Dans ce cas, vous pouvez utiliser `load`. ```html
요약 정보를 불러오는 중...
``` Ce code envoie une requête dès que l'élément est chargé et remplace ou met à jour l'élément lui-même avec la réponse. Il peut également être utilisé pour charger certaines zones relativement lourdes plus tard, au lieu de rendre toute la page côté serveur. C'est-à-dire qu'il s'adapte bien aux simples schémas de **chargement différé**. --- ### `revealed` : Exécuter quand l'élément apparaît à l'écran {#sec-c2414c692dd8} Ce déclencheur a un nom très intuitif. Il envoie une requête lorsque l'élément apparaît à l'écran. ```html
더 많은 글을 불러오는 중...
``` Cette méthode est couramment utilisée pour implémenter le **défilement infini**. Lorsque l'utilisateur fait défiler la page vers le bas et que l'élément devient visible, le bloc de données suivant est chargé et ajouté à la suite. C'est très attrayant car cela permet d'implémenter un défilement infini assez fluide sans avoir à manipuler directement l'Intersection Observer en JavaScript. Cependant, `revealed` est simple et pratique, mais peut sembler insuffisant lorsque un contrôle très fin est nécessaire. Dans ce cas, `intersect` est plus approprié. --- ### `intersect` : Gérer l'intersection avec la fenêtre d'affichage de manière plus précise {#sec-28f34a79a4dd} Si `revealed` est plus proche de la notion de « est-ce visible ? », `intersect` gère de manière plus précise **dans quelle mesure et à quel moment un élément croise la fenêtre d'affichage**. ```html
분석 영역 로딩 중...
``` Dans cet exemple, une requête est envoyée une seule fois au moment où l'élément croise la fenêtre d'affichage. Cette approche est idéale dans les cas suivants : - Charger des sections lourdes plus tard sur une longue page - Enregistrer le moment de l'affichage d'une publicité/bannière - Charger des données uniquement lorsqu'une zone spécifique est réellement visible - Remplir le contenu progressivement en fonction du défilement C'est une fonctionnalité que l'on est amené à utiliser au moins une fois pour le défilement infini, le lazy loading et les écrans où l'optimisation des performances est cruciale. --- ## Dialogue entre serveur et client : l'en-tête `HX-Trigger` {#sec-4c3d24e0673e} En utilisant [[HTMX]], on atteint un point où l'envoi de requêtes par le navigateur seul ne suffit plus. Le moment vient où l'on souhaite que **d'autres éléments de l'interface utilisateur réagissent également après la fin de la réponse du serveur**. Par exemple, dans les situations suivantes : - Je veux recharger la liste une fois l'enregistrement terminé. - Je veux afficher un message de succès après l'enregistrement. - Je veux mettre à jour le nombre du compteur en même temps. Bien que tout cela puisse être regroupé côté client avec JavaScript, HTMX permet au serveur de déclencher des événements via des en-têtes. Par exemple, dans une vue [[Django]] : ```python from django.http import HttpResponse import json def save_item(request): response = HttpResponse("
저장 완료
") response["HX-Trigger"] = json.dumps({ "itemSaved": { "message": "저장이 완료되었습니다." } }) return response ``` Ensuite, côté client, ces événements peuvent être utilisés : ```html
``` L'avantage de cette structure est clair. Le serveur, après avoir traité la requête d'enregistrement, n'envoie pas seulement un « HTML d'enregistrement terminé », mais peut également envoyer des signaux pour des réactions ultérieures, tels que **« maintenant, mets à jour la liste » ou « affiche une notification »**. En d'autres termes, le serveur et le client communiquent au-delà d'une simple relation requête-réponse, en utilisant une structure événementielle plus souple. Cela peut sembler insignifiant au début, mais à mesure que l'interface utilisateur s'agrandit, ce modèle devient de plus en plus puissant. --- ## Conclusion {#sec-c62364d3c7cd} Dans cet article, nous avons passé en revue les attributs de contrôle clés de [[HTMX]], en nous concentrant sur les fonctionnalités avancées centrées sur `hx-trigger`. En résumé, voici les points essentiels : 1. `hx-trigger` détermine **quand une requête doit être déclenchée**. 2. L'attribut trigger inclut des ÉVÉNEMENTS DOM de navigateur standard et des ÉVÉNEMENTS spécifiques à HTMX. 3. Les déclencheurs conditionnels permettent de déclencher des requêtes uniquement dans des situations spécifiques. 4. Les attributs modificateurs permettent d'ajuster finement les événements. 5. L'en-tête `HX-Trigger` permet au serveur de déclencher des actions ultérieures côté client. C'est à peu près tout ce que je peux résumer pour cet article. Le fait que tout cela soit possible **sans une seule ligne de JavaScript** est vraiment appréciable. Pour être précis, il faudrait dire **« sans une seule ligne de JavaScript que j'ai écrite »**, car le code [[JavaScript]] chargé via le CDN s'exécute déjà dans le navigateur. **Articles connexes** : - [Simplifier le développement web dynamique avec Django et HTMX (Partie 1)](/ko/whitedec/2025/1/27/django-htmx-dynamic-web-simplification/) - [Simplifier le développement web dynamique avec Django et HTMX - Ajax (Partie 2)](/ko/whitedec/2025/1/27/django-htmx-dynamic-web-simplification-2/) - [Simplifier le développement web dynamique avec Django et HTMX (Partie 3) : Méthodes d'intégration Django](/ko/whitedec/2025/1/27/django-htmx-dynamic-web-simplification-3/) - [Simplifier le développement web dynamique avec Django et HTMX (Partie 4) : Méthodes de transmission de la charge utile](/ko/whitedec/2025/1/27/django-htmx-csrf-token-integration/) - [Simplifier le développement web dynamique avec Django et HTMX : Utilisation des formulaires et des sérialiseurs](/ko/whitedec/2026/4/22/django-htmx-forms-serializer-usage/)