Techioz Blog

新しい部分がターボ フレームでレンダリングされるときに自動スクロールするにはどうすればよいですか?

概要

新しい部分がターボフレームでレンダリングされ、ページに小さなフォームがあり、ボタンをクリックすると新しいフォームをレンダリングするイベントがトリガーされるときに、JavaScriptで強制的にスクロールしようとすると少し問題が発生します。新しいフォームが追加されたとき、フォームの数が十分であれば、縦スクロールを作成します。

そこで、ボタンのクリック時にイベントリスナーを追加しようとします。クリックすると、コンテナscrollHeightをキャッチし、clientHeightと比較します。それが大きい場合、要素scrollTopの属性を実行します。これはコードです。

button.addEventListener("click", function (e) {
    let container = document.querySelector("#container-travellers")
    if (container.scrollHeight > container.clientHeight) {
        console.log('should scroll')
        container.scrollTop = container.scrollHeight;
      }
  })

私はよく検索し、ターボフレームの自動スクロールプロパティなどのターボイベント、またはturbo:submit-endのようなイベントでそれを実行しようとしましたが、この両方のイベントではスクロールは発生せず、コンソールログのみが表示され、条件付きが機能しています。

それが重要であれば、これはターボストリームとターボフレーム呼び出しの HTML コードです

 <%= turbo_stream_from 'checkout_stream' %>
 <div id="container-travellers" class="shadow-md flex flex-col rounded-md bg-white p-2 w-full max-h-[690px] gap-2 scroll-smooth overflow-auto" data-autoscroll-block="end">
      <%= turbo_frame_tag 'travellers', id:'travellers_frame', class:"flex flex-col gap-4" do %>
          <%= render partial: 'travellers/traveller_form'%>
      <% end %>
      <%= link_to "Add New", add_new_traveller_path, id:'new_traveller', class:"w-full text-center bg-[#{tw_color_purple('600')}] py-1 text-white hover:bg-[#{tw_color_purple('700')}] rounded", data: {
                  turbo_method: :post,
        } %>
 </div>

解決策(最善ではありません): Turbo ヘルパー、イベント、属性を使用していくつかの解決策を見つけようとしましたが、どれも機能しませんでした。JavaScript を実行して機能させ、イベント DOMNodeInserted をリッスンします。そのため、新しいパーシャルがストリーミングされてフレームに追加されると、イベントがトリガーされ、スクロール機能が実行されます。

これは私が知っている最善の解決策ではありませんが、私にとっては問題は解決しました。

解決策

公式ドキュメントを読むと、次のことがわかりました

Turbo_frame 要素に次の HTML 属性を追加してみてはいかがでしょうか

<%= turbo_frame_tag 'travellers', id:'travellers_frame', class:"flex flex-col gap-4", 'data-autoblock-scroll': 'end' do %>

または

<%= turbo_frame_tag 'travellers', id:'travellers_frame', class:"flex flex-col gap-4", 'data-autoscroll-behavior': 'smooth' do %>