首頁 >web前端 >js教程 >透過 Turbo Streams 實現平滑過渡

透過 Turbo Streams 實現平滑過渡

DDD
DDD原創
2024-10-11 10:26:01519瀏覽

本文原刊於 Rails Designer


使用 Turbo Streams,您可以更新應用程式的特定部分。插入聊天訊息、更新個人資料圖片或插入正在建立報告警報。

Turbo Streams 提供的精確性非常好。但往往它的唐突,對我來說不太有吸引力。新組件就在那裡(或者如果您將其刪除,則不存在)。

我想為我的應用程式添加更多樂趣,而這項技術正是可以做到這一點。我之前探索了多種技術來在插入或刪除元素時添加某種過渡或動畫。多年來我在生產中使用它時對其進行了微調。我可以說我對我今天概述的技術的工作原理感到滿意。

首先,這將是最終結果:

Smooth Transitions with Turbo Streams

使用方法如下:

<%= 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 %>

如果您正在使用 Rails Designer 它已包含,可供您使用。贏了! ?

這裡有相當多的移動元素來讓它運行,但從上面的程式碼範例中可以看出,用法非常乾淨且可自訂。

讓我們開始吧。

第一步是建立turbo_stream_action_tag_with_block 幫助器。這是必要的,因為可用的 Turbo_stream_action_tag 幫助程式不允許傳遞區塊(例如渲染 CollectionComponent),而且預設的 Turbo 流 Rails 幫助程式不會傳遞資料屬性。不過這很簡單:

# 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

下一步是為 Turbo:before-stream-render 新增監聽器並添加一些自訂行為。

// 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")
}

哇!這看起來很嚇人!真的還不錯!它攔截turbo:before-stream-render事件,檢查目標元素的資料集的特定轉換屬性(例如data-transition-start)。對於輸入元素,它將它們設定為隱藏並添加一個 appear 資料控制器。為了離開元素,它增加了一個消失資料控制器。

?想要作為 Ruby on Rails 開發人員更輕鬆地編寫和理解 JavaScript?查看《JavaScript for Rails 開發人員》一書

確保將其匯入到您的application.js

 // app/javascript/application.js
 import "@hotwired/turbo-rails"
 import "./controllers"
 import "./utilities/turbo_stream_render.js"

 // …

現在讓我們來建立這兩個控制器。它們非常簡單,並且依賴很酷的 el-transition 庫。確保將其添加到您的應用程式中(透過 NPM 或 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()
    })
  }
}

完成這一切後,您現在可以使用渦輪流為任何添加或刪除的元素添加平滑過渡。

只需將一些資料屬性(資料:{transition_enter: ""})附加到渦輪流中即可享受流暢的旅程。

您可以使用 el-transition 支援的相同資料屬性:

  • 資料轉換輸入;
  • 資料轉換-輸入-開始;
  • 資料轉換-進入結束;
  • 資料轉換離開;
  • 資料轉換-離開-開始;
  • 資料轉換離開結束。

用於添加元素:

<%= 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 %>

刪除元素:

<%= 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"} %>

以上是透過 Turbo Streams 實現平滑過渡的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn