查看源代码 Phoenix.LiveView.JS (Phoenix LiveView v0.20.17)

提供用于在客户端执行 JavaScript 实用程序操作的命令。

JS 命令支持各种实用程序操作,用于满足常见的客户端需求,例如添加或删除 CSS 类、设置或删除标签属性、显示或隐藏内容以及使用动画进行过渡。虽然这些操作可以通过客户端钩子来实现,但 JS 命令是 DOM 修补感知的,因此通过 JS API 应用的操作将保留在来自服务器的修补程序中的元素上。

除了纯粹的客户端实用程序之外,JS 命令还包括一个丰富的 push API,用于扩展默认的 phx- 绑定推送,并提供选项以自定义目标、加载状态和额外的有效负载值。

客户端实用程序命令

包含以下实用程序

  • add_class - 向元素添加类,可以选择过渡
  • remove_class - 从元素中删除类,可以选择过渡
  • toggle_class - 设置或删除元素的类,可以选择过渡
  • set_attribute - 在元素上设置属性
  • remove_attribute - 从元素中删除属性
  • toggle_attribute - 基于属性存在情况设置或删除元素属性。
  • show - 显示元素,可以选择过渡
  • hide - 隐藏元素,可以选择过渡
  • toggle - 根据可见性显示或隐藏元素,可以选择过渡
  • transition - 对元素应用临时过渡以进行动画
  • dispatch - 向元素分派 DOM 事件

例如,以下模态组件可以在客户端上显示或隐藏,而无需访问服务器

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-* 属性也将包含在有效负载中,它们的值将被直接提供给 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 历史记录。

将焦点集中在最后推送的元素上。

将事件推送到服务器。

将焦点从源元素推送到稍后弹出。

从元素中删除属性。

从元素中删除类。

在元素上设置属性。

显示元素。

切换元素可见性。

基于属性存在情况设置或删除元素属性。

根据存在情况添加或删除元素类。

元素过渡。

类型

@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 - 要分派的字符串事件名称。

注意:所有分派的事件都属于 CustomEvent 类型,除了 "click"。对于 "click",会分派一个 MouseEvent 以正确模拟 UI 点击。

对于发出的 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 - 要在隐藏之前应用的类字符串,或一个包含过渡类、要应用以启动过渡的类和结束过渡类的 3 元组,例如:{"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 事件。默认值为 false
  • :value - 要发送到服务器的值映射。这些值将与元素上存在的任何 phx-value-* 属性合并。合并时所有键都将被视为字符串。

示例

<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.

基于属性存在情况设置或删除元素属性。

接受包含两个或三个元素的元组

  • {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 元组,例如:{"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.