2021/04/21 追記

Turbo Frame のリファレンスをよく見たら load イベント時のコールバックを設定できました。

export default class extends Controller {
  static targets = [ 'frame' ];

  connect() {
    this.frameTarget.loaded.then(() => {
      // do something...
    });
  }
}

これで Turbo Frame の読み込みが完了したタイミングで任意の処理を実行することが出来ます。

追記ここまで


Hotwire の Turbo Frame は現時点の最新バージョン ( v7.0.0-beta.5 ) では Trubo Frame の表示イベントは存在しません(ただ対応プルリクは出ているので、将来的にはサポートされるかもしれません)。

Turbo Frame はページ内の一部を非同期に表示させる機能なので、表示切り替え時にフェードイン・アウトや、読み込みインジケーターを表示させたりがしたくなります。というわけで、今回は Turbo Frame の表示切り替えを検知して任意の処理をできるようにします。

さっそく実現するためのコードです。やっていることは原始的で Stimulus のコントローラで Turbo Frame タグを MutationObserver 使って変更監視するだけです。Turbo Frame はコンテンツの読み込み時には busy 属性をつけてくれるので、busy 属性の変更を検知することで読み込み中・読み込み完了を知ることができます。

import { Controller } from 'stimulus';

export default class extends Controller {
  static targets = [ 'frame' ];

  connect () {
    this.observer = new MutationObserver(this.frameMutated.bind(this));
    this.observer.observe(this.frameTarget, { attributes: true });
  }

  disconnect () {
    this.observer.disconnect();
    delete this.observer;
  }

  frameMutated () {
    if (this.frameTarget.hasAttribute('busy')) {
      console.log('loading...');
    } else {
      console.log('ready!');
    }
  }
}
<%= turbo_frame_tag 'frame_detail', data: { controller: 'frame', frame_target: 'frame' } %>
<%= link_to 'Show', hoge_path, data: { turbo_frame: 'frame_detail' } %>

簡単ですね。