当新的Turbo Frame加载时,我该如何执行JavaScript

8

我在我的Rails应用中使用Turbo Frames,在每个页面上

<turbo-frame id="messagesFrame" src="/chats">
</turbo-frame>

网页可以正常加载,当链接被点击时,框架被替换。我已经在这个框架中设置了overflow-y: scroll,在页面上创建了一个可滚动的框架。每次加载新页面到框架中,我希望它能滚动到底部。如何实现?最好使用纯JavaScript。

1个回答

17

有几种方法可以做到这一点。

当惰性加载框架或触发框架重新加载的链接时,Turbo 应该在 document 上触发 turbo:before-fetch-requestturbo:before-fetch-response 事件。

你可以尝试类似于以下的操作:

document.addEventListener("turbo:before-fetch-response", function (e) {
  let frame = document.getElementById("messagesFrame");
  if (frame.complete) {
   frame.scrollTo(0, frame.scrollHeight)
  } else {
    frame.loaded.then(() => frame.scrollTo(0, frame.scrollHeight))
  }
})

来源: Turbo 事件 => https://turbo.hotwired.dev/reference/events

Frame.complete 和 Frame.loaded => https://turbo.hotwired.dev/reference/frames


我建议使用上述方法,因为您指定了普通的JavaScript。对于大多数与Turbo相关的事情,建议使用StimulusJS。

您可以编写一个Stimulus (https://stimulus.hotwired.dev/) 控制器,将其附加到显示在TurboFrame内部的body元素上,并在connect方法中执行相同的操作。

这样,无论帧内的内容何时刷新,Stimulus控制器都将运行,您不必担心事件被触发的顺序。


谢谢!我选择Stimulus版本(只提到了vanilla以避免使用JQuery,因为我是新手,忘记了Stimulus的存在),但代码抛出“frame.loaded未定义”的错误。如果我去掉if语句,直接运行scrollTo(),它就很好用,if语句只是为了确保它首先被加载吗?由于某种原因,它还在页面顶部注入了一堆空格 :-\ - tsvallender
不确定是什么,但我所做的各种CSS更改似乎已经解决了空白问题。 - tsvallender
是的,这取决于您正在运行哪个版本的 Turbo/Hotwire。在最新版本(beta-5)中,“loaded”是一个属性,它返回一个 Promise,在帧加载完成时解析。 - SubXaero
在帧内容中使用刺激控制器时,您不需要if语句,因为控制器仅在帧完成加载时运行 :) - SubXaero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接