檢視原始程式 Phoenix.LiveView.JS (Phoenix LiveView v0.20.17)

提供了在用戶端執行 JavaScript 公用程式作業的指令。

JS 指令支援許多常見用戶端需求的公用程式作業,例如新增或移除 CSS 類別、設定或移除標籤屬性、顯示或隱藏內容以及藉由動畫淡入和淡出。雖然可以透過用戶端掛勾完成這些作業,但 JS 指令會感知 DOM 修補,因此 JS API 套用作業將維持伺服器修補後的元素。

除了純粹的用戶端公用程式,JS 指令還包含一個豐富的 push API,用於透過自訂目標、載入狀態和額外有效負載值選項來擴充預設的 phx- binding 推送。

用戶端公用程式指令

以下包括的公用程式

  • add_class - 新增類別至元素,可選取轉場效果
  • remove_class - 從元素移除類別,可選取轉場效果
  • toggle_class - 基於元素是否存在類別來設定或移除類別,可選取轉場效果
  • set_attribute - 設定元素的屬性
  • remove_attribute - 從元素移除屬性
  • toggle_attribute - 基於屬性是否存在來設定或移除元素屬性。
  • show - 顯示元素,可選取轉場效果
  • hide - 隱藏元素,可選取轉場效果
  • toggle - 基於可見性顯示或隱藏元素,可選取轉場效果
  • transition - 對元素套用暫時轉場效果以播放動畫
  • dispatch - 將 DOM 事件派送至元素

例如,以下 modal 元件可以在用戶端顯示或隱藏,而不用連線伺服器

alias Phoenix.LiveView.JS

def hide_modal(js \\ %JS{}) do
  js
  |> JS.hide(transition: "fade-out", to: "#modal")
  |> JS.hide(transition: "fade-out-scale", to: "#modal-content")
end

def modal(assigns) do
  ~H"""
  <div id="modal" class="phx-modal" phx-remove={hide_modal()}>
    <div
      id="modal-content"
      class="phx-modal-content"
      phx-click-away={hide_modal()}
      phx-window-keydown={hide_modal()}
      phx-key="escape"
    >
      <button class="phx-modal-close" phx-click={hide_modal()}>✖</button>
      <p><%= @text %></p>
    </div>
  </div>
  """
end

加強的事件推播

phx- 事件推播至伺服器時,push/1 指令可讓您擴充內建的推播事件處理。例如,您可能希望鎖定特定的元件、指定額外的有效負載值來包含事件、對外部元素套用載入狀態等。例如,針對這個基本的 phx-click 事件

<button phx-click="inc">+</button>

想像您需要鎖定您的目前元件,並且在用戶端等待伺服器確認時套用載入狀態至父端容器

alias Phoenix.LiveView.JS

<button phx-click={JS.push("inc", loading: ".thermo", target: @myself)}>+</button>

指令組合也會包含所有其他程式功能。例如,在推播時加入一個類別

<button phx-click={
  JS.push("inc", loading: ".thermo", target: @myself)
  |> JS.add_class("warmer", to: ".thermo")
}>+</button>

任何 phx-value-* 屬性也會包含在 payload 中,其值將會被直接提供至 push/1 的值覆寫。任何 phx-target 屬性也會同時使用及覆寫。

<button
  phx-click={JS.push("inc", value: %{limit: 40})}
  phx-value-room="bedroom"
  phx-value-limit="this value will be 40"
  phx-target={@myself}
>+</button>

使用 JS.dispatch/1window.addEventListener 的自訂 JS 事件

dispatch/1 可用於向元素傳送自訂的 JavaScript 事件。例如,你可以使用 JS.dispatch("click", to: "#foo"),向元素傳送一個點擊事件。

這也表示你可以透過使用 JavaScript 的 window.addEventListener 並使用 dispatch/1 呼叫它們,來擴充你的元素中的自訂事件。例如,想像你想要在應用程式中提供複製到剪貼簿的功能。你可以為它加入一個自訂事件

window.addEventListener("my_app:clipcopy", (event) => {
  if ("clipboard" in navigator) {
    const text = event.target.textContent;
    navigator.clipboard.writeText(text);
  } else {
    alert("Sorry, your browser does not support clipboard copy.");
  }
});

現在你可以有一個按鈕長成這樣

<button phx-click={JS.dispatch("my_app:clipcopy", to: "#element-with-text-to-copy")}>
  Copy content
</button>

結合使用 dispatch/1window.addEventListener 是強大的機制,可增加從 LiveView 程式碼觸發客戶端動作的次數。

你也可以使用 window.addEventListener 來監聽從伺服器推播的事件。更多資訊可以參考我們的 JS 互操作性說明

摘要

函式

向元素中加入類別。

傳送事件至 DOM。

執行放置在元素屬性中的 JS 指令。

將焦點傳送到選擇器。

將焦點傳送到選擇器中的第一個可聚焦的子項。

隱藏元素。

傳送導覽事件至伺服器,並更新瀏覽器的 pushState 歷程記錄。

將貼片事件傳送至伺服器並更新瀏覽器的 pushState 歷程。

請參閱 patch/1

讓最後推入的元素獲得焦點。

將事件推入伺服器。

請參閱 push/1

將焦點從來源元素推入,以便稍後彈出。

從元素中移除屬性。

從元素中移除類別。

在元素上設定屬性。

顯示元素。

請參閱 show/1

切換元素可見性。

請參閱 toggle/1

根據屬性的存在性設定或移除元素屬性。

根據存在性新增或移除元素類別。

執行元素過場。

類型

@opaque internal()
@type t() :: %Phoenix.LiveView.JS{ops: internal()}

函式

向元素中加入類別。

  • names - 含有要新增之一或多個類別名稱的字串。

選項

  • :to - 新增類別的 DOM 選擇器(選用)。預設為互動元素。
  • :transition - 在新增類別之前套用的類別字串,或包含過場類別、用於開始過場的類別及結束過場類別的 3 元組,例如:{"ease-out duration-300", "opacity-0", "opacity-100"}
  • :time - 套用轉場的毫秒,來自 :transition。預設為 200。

範例

<div id="item">My Item</div>
<button phx-click={JS.add_class("highlight underline", to: "#item")}>
  highlight!
</button>

參閱 add_class/1

連結至此函式

add_class(js, names, opts)

檢視原始碼

參閱 add_class/1

連結至此函式

dispatch(js \\ %JS{}, event)

檢視原始碼

傳送事件至 DOM。

  • event - 字串事件名稱以進行調度。

註:調度中所有事件的類型都為 自訂事件"click" 除外。對於 "click"滑鼠事件會進行調度,以恰當地模擬使用者介面點按。

對於發出的 CustomEvent,事件詳細資料將包含 dispatcher,它參考向目標元素調度 JS 事件的 DOM 節點。

選項

  • :to - 一個可選的 DOM 選擇器可傳送事件。預設為互動的元素。
  • :detail - 一個可選的詳細資料對應可以和用戶端事件一起調度。詳細資料將在事件聆聽器的 event.detail 中提供。
  • :bubbles – 布林旗標決定事件是否會冒泡。預設為 true

範例

window.addEventListener("click", e => console.log("clicked!", e.detail))

<button phx-click={JS.dispatch("click", to: ".nav")}>Click me!</button>
連結至此函式

dispatch(js, event, opts)

檢視原始碼

參閱 dispatch/2

執行放置在元素屬性中的 JS 指令。

  • attr - 指定 JS 指令的字串屬性

選項

  • :to - 一個可選的 DOM 選擇器可以從中擷取屬性。預設為目前的元素。

範例

<div id="modal" phx-remove={JS.hide("#modal")}>...</div>
<button phx-click={JS.exec("phx-remove", to: "#modal")}>close</button>

參閱 exec/1

參閱 exec/1

將焦點傳送到選擇器。

選項

  • :to - 一個可選的 DOM 選擇器可以傳送焦點。預設為目前的元素。

範例

JS.focus(to: "main")

參閱 focus/1

連結至此函式

focus_first(opts \\ [])

檢視原始碼

將焦點傳送到選擇器中的第一個可聚焦的子項。

選項

  • :to - 一個可選的 DOM 選擇器可以獲得焦點。預設為目前的元素。

範例

JS.focus_first(to: "#modal")

參閱 focus_first/1

隱藏元素。

選項

  • :to - 一個可選的 DOM 選擇器可以隱藏。預設為互動的元素。
  • :transition - 一串類別,將在隱藏之前套用,或是一組包含轉場類別、開始轉場時套用的類別和結束轉場類別的三元組,例如:{"ease-out duration-300", "opacity-100", "opacity-0"}
  • :time - 套用轉場的毫秒,來自 :transition。預設為 200。

在此過程中,以下事件會傳送到隱藏的元素

  • 當觸發客戶端的動作時,phx:hide-start 會被派遣。
  • :time 指定的時間後,phx:hide-end 會被派遣。

範例

<div id="item">My Item</div>

<button phx-click={JS.hide(to: "#item")}>
  hide!
</button>

<button phx-click={JS.hide(to: "#item", transition: "fade-out-scale")}>
  hide fancy!
</button>

參閱 hide/1

將貼片事件傳送至伺服器並更新瀏覽器的 pushState 歷程。

選項

  • :replace - 是否要取代瀏覽器的 pushState 歷程。預設為 false

範例

JS.patch("/my-path")

請參閱 patch/1

請參閱 patch/1

連結至此函式

pop_focus(js \\ %JS{})

檢視原始碼

讓最後推入的元素獲得焦點。

範例

JS.pop_focus()

將事件推入伺服器。

  • event - 事件名稱的字串要推送。

選項

  • :target - 一個選擇器或元件 ID 要推送。這個值會覆蓋元件上出現的任何 phx-target 屬性。
  • :loading - 套用 Phx 讀取類別的選擇器。
  • :page_loading - 布林值啟動 phx:page-loading-start 和 phx:page-loading-stop 事件給這一次的 push。預設為 false
  • :value - 地圖值傳送到伺服器。這些值會合併於元件上出現的任何 phx-value-* 屬性。所有在合併時候的 key 會當作字串來處理。

範例

<button phx-click={JS.push("clicked")}>click me!</button>
<button phx-click={JS.push("clicked", value: %{id: @id})}>click me!</button>
<button phx-click={JS.push("clicked", page_loading: true)}>click me!</button>

請參閱 push/1

請參閱 push/1

連結至此函式

push_focus(opts \\ [])

檢視原始碼

將焦點從來源元素推入,以便稍後彈出。

選項

  • :to - 一個任選的 DOM 選擇器要推送焦點。預設為目前的元件。

範例

JS.push_focus()
JS.push_focus(to: "#my-button")

請參閱 push_focus/1

連結至此函式

remove_attribute(attr)

檢視原始碼

從元素中移除屬性。

  • attr - 要移除的字串屬性名稱。

選項

  • :to - 一個任選的 DOM 選擇器移除屬性。預設為互動的元件。

範例

<button phx-click={JS.remove_attribute("aria-expanded", to: "#dropdown")}>
  hide
</button>
連結至此函式

remove_attribute(attr, opts)

檢視原始碼

請參閱 remove_attribute/1

連結至此函式

remove_attribute(js, attr, opts)

檢視原始碼

請參閱 remove_attribute/1

從元素中移除類別。

  • names - 一個字串包含一個或多個要移除的類別名稱。

選項

  • :to - 一個任選的 DOM 選擇器移除類別。預設為互動的元件。
  • :transition - 在移除類別之前要套用的類別字串,或包含轉場類別、要套用的類別以開始轉場,以及結束轉場類別的 3 元組,例如: {"ease-out duration-300", "opacity-0", "opacity-100"}
  • :time - 套用轉場的毫秒,來自 :transition。預設為 200。

範例

<div id="item">My Item</div>
<button phx-click={JS.remove_class("highlight underline", to: "#item")}>
  remove highlight!
</button>
連結至此函式

remove_class(js, names)

檢視原始碼

請參閱 remove_class/1

連結至此函式

remove_class(js, names, opts)

檢視原始碼

請參閱 remove_class/1

在元素上設定屬性。

接受包含字串屬性名稱/值對的元組。

選項

  • :to - 要新增屬性的 DOM 選擇器(選用)。預設為互動的元素。

範例

<button phx-click={JS.set_attribute({"aria-expanded", "true"}, to: "#dropdown")}>
  show
</button>
連結至此函式

set_attribute(js, opts)

檢視原始碼

請參閱 set_attribute/1

連結至此函式

set_attribute(js, arg, opts)

檢視原始碼

請參閱 set_attribute/1

顯示元素。

選項

  • :to - 要顯示的 DOM 選擇器(選用)。預設為互動的元素。
  • :transition - 在顯示之前要套用的類別字串,或包含轉場類別、要套用的類別以開始轉場,以及結束轉場類別的 3 元組,例如: {"ease-out duration-300", "opacity-0", "opacity-100"}
  • :time - 套用轉場的毫秒,來自 :transition。預設為 200。
  • :display - 要在顯示時設定的顯示值(選用)。預設為 "block"

在這個過程中,會傳送下列事件給顯示的元素

  • 在客戶端觸發動作時,會傳送 phx:show-start
  • :time 指定的時間後,會傳送 phx:show-end

範例

<div id="item">My Item</div>

<button phx-click={JS.show(to: "#item")}>
  show!
</button>

<button phx-click={JS.show(to: "#item", transition: "fade-in-scale")}>
  show fancy!
</button>

請參閱 show/1

切換元素可見性。

選項

  • :to - 要切換的 DOM 選擇器(選用)。預設為互動的元素。
  • :in - 在切換至啟用時要套用的類別字串,或包含轉場類別、要套用的類別以開始轉場,以及結束轉場類別的 3 元組,例如: {"ease-out duration-300", "opacity-0", "opacity-100"}
  • :out - 在切換為停用時要套用的類別字串,或包含轉場類別、要套用的類別以開始轉場,以及結束轉場類別的 3 元組,例如: {"ease-out duration-300", "opacity-100", "opacity-0"}
  • :time - 套用轉場類別 :in:out 的時間(毫秒)。預設為 200。
  • :display - 要在切換至啟用時設定的顯示值(選用)。預設為 "block"

切換動作在用戶端完成時,phx:show-startphx:hide-start 以及 phx:show-endphx:hide-end 事件將會送往已切換的元素。

範例

<div id="item">My Item</div>

<button phx-click={JS.toggle(to: "#item")}>
  toggle item!
</button>

<button phx-click={JS.toggle(to: "#item", in: "fade-in-scale", out: "fade-out-scale")}>
  toggle fancy!
</button>

請參閱 toggle/1

根據屬性的存在性設定或移除元素屬性。

接受兩個或三個元素組成的 tuple

  • {attr, val} - 設定屬性值或移除屬性
  • {attr, val1, val2} - 在 val1val2 之間切換屬性

選項

  • :to - 設定或移除屬性的 DOM 選擇器,預設為要進行互動的元素。

範例

<button phx-click={JS.toggle_attribute({"aria-expanded", "true", "false"}, to: "#dropdown")}>
  toggle
</button>

<button phx-click={JS.toggle_attribute({"open", "true"}, to: "#dialog")}>
  toggle
</button>
連結至此函式

toggle_attribute(js, opts)

檢視原始碼

請參閱 toggle_attribute/1

連結至此函式

toggle_attribute(js, arg, opts)

檢視原始碼

請參閱 toggle_attribute/1

根據存在性新增或移除元素類別。

  • names - 包含要切換的類別名稱字串。

選項

  • :to - 目標的 DOM 選擇器,預設為要進行互動的元素。
  • :transition - 在新增類別之前套用的類別字串,或包含過場類別、用於開始過場的類別及結束過場類別的 3 元組,例如:{"ease-out duration-300", "opacity-0", "opacity-100"}
  • :time - 套用轉場的毫秒,來自 :transition。預設為 200。

範例

<div id="item">My Item</div>
<button phx-click={JS.toggle_class("active", to: "#item")}>
  toggle active!
</button>
連結至此函式

toggle_class(js, names)

檢視原始碼
連結至此函式

toggle_class(js, names, opts)

檢視原始碼
連結至此函式

transition(transition)

檢視原始碼

執行元素過場。

  • transition - 在移除類別前加上的類別字串,或是包含切換類別、開始切換的類別以及結束切換的類別的 3-tuple,例如:{"ease-out duration-300", "opacity-0", "opacity-100"}

切換對於暫時將動畫類別加入元素十分有用,例如變更內容時要讓內容醒目。

選項

  • :to - 套用切換的 DOM 選擇器,預設為要進行互動的元素。
  • :time - 套用轉場的毫秒,來自 :transition。預設為 200。

範例

<div id="item">My Item</div>
<button phx-click={JS.transition("shake", to: "#item")}>Shake!</button>
連結至此函式

transition(transition, opts)

檢視原始碼

請參閱 transition/1

連結至此函式

transition(js, transition, opts)

檢視原始碼

請參閱 transition/1