【问题标题】:How can I execute JavaScript when a new Turbo Frame is loaded加载新的 Turbo Frame 时如何执行 JavaScript
【发布时间】:2021-04-29 10:05:28
【问题描述】:

我在我的 Rails 应用程序中使用 Turbo Frames,并且在每个页面上都有

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

这可以很好地加载,并且在单击链接时会按预期替换框架。在这个框架中,我设置了overflow-y: scroll,在页面上创建了一个可滚动的框架。每次在框架中加载新页面时,我都希望它滚动到底部。我怎样才能做到这一点?理想情况下使用原生 JavaScript。

【问题讨论】:

    标签: javascript ruby-on-rails hotwire-rails turbo turbo-frames


    【解决方案1】:

    您可以通过多种方式做到这一点。

    当延迟加载帧或触发帧重新加载的链接时,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


    我建议使用上述方法,因为您指定了 vanilla Javascript。大多数与 Turbo 相关的事情的推荐方法是使用 StimulusJS。

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

    这样,每当刷新框架内的内容时,Stimulus 控制器就会运行,您不必担心触发事件的顺序。

    【讨论】:

    • 谢谢!选择 Stimulus 版本(只声明 vanilla 以避免 JQuery,这是新手并忘记了 Stimulus 的存在),但代码抛出“frame.loaded is undefined”。如果我摆脱 if 语句并只运行 scrollTo(),它工作得很好,if 语句是否只是为了确保它首先被加载?由于某种原因,它还在页面顶部附近注入了一堆空白:-\
    • 不确定是什么,但我一直在做的各种 CSS 更改似乎已经消除了空白问题。
    • 是的,具体取决于您运行的涡轮增压/热线版本。在最新版本(beta-5)中,loaded 是一个属性,它返回一个在框架完成加载时解析的承诺。
    • 在帧内容中使用刺激控制器时,您不需要if 语句,因为控制器仅在帧完成加载时运行:)
    猜你喜欢
    • 2016-02-16
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    相关资源
    最近更新 更多