Skip to content
Advertisement

How can I execute JavaScript when a new Turbo Frame is loaded

I am using Turbo Frames in my Rails app and have, on every page

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

This loads in fine, and when a link is clicked replaces the frame as expected. In this frame I have set overflow-y: scroll, creating a scrollable frame on the page. Every time a new page is loaded in the frame, I want it to scroll to the bottom. How can I achieve this? Ideally with vanilla JavaScript.

Advertisement

Answer

You could do this in several ways.

Turbo should fire a turbo:before-fetch-request and turbo:before-fetch-response on the document when lazy loaded frames, or links that trigger a frame reload.

You could do something like:

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

Sources: Turbo events => https://turbo.hotwired.dev/reference/events

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


I suggest the above method because you specified vanilla Javascript. The recommended way for most Turbo related things is to use StimulusJS.

You could write a Stimulus (https://stimulus.hotwired.dev/) controller that you attach to an element in the body that shows inside the TurboFrame, and in the connect method, do the same.

That way, whenever the content inside the frame is refreshed the Stimulus controller will run, and you don’t have to worry about the order of the events being fired.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement