Maison >interface Web >js tutoriel >Transitions fluides avec Turbo Streams
Cet article a été initialement publié sur Rails Designer
Avec Turbo Streams, vous pouvez mettre à jour des parties spécifiques de votre application. Injectez un message de chat, mettez à jour une photo de profil ou insérez une alerte Le rapport est en cours de création.
La précision offerte par Turbo Streams est excellente. Mais souvent, la brusquerie des choses ne m'attire pas trop. Le nouveau composant est juste là (ou non, si vous le supprimez).
J'aimerais ajouter un peu plus de joie à mes applications et cette technique est exactement ce que fait. J'ai déjà exploré plusieurs techniques pour ajouter une sorte de transition ou d'animation lorsqu'un élément était inséré ou supprimé. Je l'ai peaufiné au fil des années tout en l'utilisant en production. Et je peux dire que je suis satisfait du fonctionnement de la technique que je décris aujourd'hui.
Tout d'abord, voici le résultat final :
Et voici comment il est utilisé :
<%= turbo_stream_action_tag_with_block "prepend", target: "resources", data: {transition_enter: "transition ease-in duration-300", transition_enter_start: "opacity-0", transition_enter_end: "opacity-100"} do %> <%= render ResourceComponent.new(resource: @resource) %> <% end %>
Si vous utilisez Rails Designer il est inclus pour vous et prêt à l'emploi. Gagnant! ?
Il y a pas mal d'éléments mobiles ici pour le faire démarrer, mais comme le montre l'exemple de code ci-dessus, l'utilisation est vraiment propre et personnalisable.
Commençons.
La première étape consiste à créer l'assistant turbo_stream_action_tag_with_block. Ceci est nécessaire, car l'assistant turbo_stream_action_tag disponible ne permet pas de transmettre un bloc (par exemple, render CollectionComponent) et les assistants Turbo stream Rails par défaut ne transmettent pas les attributs de données. Mais c'est assez simple :
# app/helpers/turbo_stream_helper.rb module TurboStreamHelper def turbo_stream_action_tag_with_block(action, target: nil, targets: nil, **options, &block) template_content = block_given? ? capture(&block) : nil turbo_stream_action_tag(action, target: target, targets: targets, template: template_content, **options) end end
La prochaine étape consiste à ajouter un écouteur pour turbo:before-stream-render et à ajouter un comportement personnalisé.
// app/javascript/utilities/turbo_stream_render.js document.addEventListener("turbo:before-stream-render", (event) => { const { target } = event if (!(target.firstElementChild instanceof HTMLTemplateElement)) return const { dataset, templateElement } = target const { transitionEnter, transitionLeave } = dataset if (transitionEnter !== undefined) { transitionEnter(event, templateElement, dataset) } if (transitionLeave !== undefined) { handleTransitionLeave(event, target, dataset) } }) const handleTransitionEnter = (event, templateElement, dataset) => { event.preventDefault() const firstChild = templateElement.content.firstElementChild Object.assign(firstChild.dataset, dataset) firstChild.setAttribute("hidden", "") firstChild.setAttribute("data-controller", "appear") event.target.performAction() } const handleTransitionLeave = (event, target, dataset) => { const leaveElement = document.getElementById(target.target) if (!leaveElement) return event.preventDefault() Object.assign(leaveElement.dataset, dataset) leaveElement.setAttribute("data-controller", "disappear") }
Wow ! Cela a l'air effrayant ! Ce n'est vraiment pas trop mal ! Il intercepte l'événement turbo:before-stream-render, vérifiant l'ensemble de données de l'élément cible pour des attributs de transition spécifiques (par exemple data-transition-start). Pour saisir des éléments, il les définit comme masqués et ajoute un contrôleur de données apparaître. Pour quitter les éléments, il ajoute un contrôleur de données disparaître.
? Vous souhaitez être plus à l'aise pour écrire et comprendre JavaScript en tant que développeur Ruby on Rails ? Consultez le livre JavaScript pour les développeurs Rails
Assurez-vous de l'importer dans votre application.js.
// app/javascript/application.js import "@hotwired/turbo-rails" import "./controllers" import "./utilities/turbo_stream_render.js" // …
Créons ces deux contrôleurs maintenant. Ils sont vraiment simples et s'appuient sur la superbe bibliothèque el-transition. Assurez-vous de l'ajouter à votre application (soit via NPM, soit importmaps).
// app/javascript/controllers/appear_controller.js import ApplicationController from "./application_controller" import { enter } from "el-transtion" export default class extends ApplicationController { connect() { enter(this.element) } }
// app/javascript/controllers/disappear_controller.js import ApplicationController from "./application_controller" import { leave } from "el-transtion" export default class extends ApplicationController { connect() { leave(this.element).then(() => { this.element.remove() }) } }
Et une fois tout cela réglé, vous pouvez désormais ajouter des transitions fluides à tout élément ajouté ou supprimé à l'aide de flux turbo.
Ajoutez simplement quelques attributs de données (data : {transition_enter: ""}) au flux turbo et profitez d'une conduite en douceur.
Vous pouvez utiliser les mêmes attributs de données pris en charge par el-transition :
Pour ajouter des éléments :
<%= turbo_stream_action_tag_with_block "prepend", target: "resources", data: {transition_enter: "transition ease-in duration-300", transition_enter_start: "opacity-0", transition_enter_end: "opacity-100"} do %> <%= render ResourceComponent.new(resource: @resource) %> <% end %>
Et pour supprimer des éléments :
<%= turbo_stream_action_tag_with_block "remove", target: dom_id(@resource), data: {transition_leave: "transition ease-in duration-300", transition_leave_start: "opacity-100", transition_leave_end: "opacity-0"} %>
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!