You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Rails应用中使用Turbo导航时出现整页重载问题求助

问题描述

基于Ruby on Rails和Turbo开发文档站点时,点击左侧侧边栏链接,右侧内容虽能正确替换,但触发了整页HTML重载,导致CSS过渡效果失效,Turbo标签内容出现两次闪烁。期望仅Turbo标签内内容更新,其余HTML保持不变,同时导航链接样式按CSS过渡生效。


相关代码

articles.html.erb

<div class='docs-split'>
    <div class='sidebar'>
        <div>
            ...

            <div class='links padding-top'>
                <%= link_to render(:partial => 'shared/primary_navigation_link', locals: { title: "Getting Started", path: "getting-started" }), 'getting-started' %>
                <%= link_to render(:partial => 'shared/primary_navigation_link', locals: { title: "Types of Charts", path: "types-of-charts" }), 'types-of-charts' %>
            </div>
        </div>
    </div>

    <div class='content'>
        <%= turbo_frame_tag "article", src: article_path(params[:title] ? params[:title] : "getting-started") do %>
            
        <% end %>
    </div>
</div>

articles_controller.rb

require 'github/markup'

class ArticlesController < ApplicationController
  def index
  end

  def open_article
    title = Rails.root.to_s + "/app/markdown/" + params[:title] + ".md"
    @content = ActionController::Base.render inline: GitHub::Markup.render(title, File.read(title))
  end
end

open_article.html.erb

<%= turbo_frame_tag "article" do %>
    <%= @content %>
<% end %>

routes.rb

Rails.application.routes.draw do
  root :to => redirect('/articles/getting-started')
  get 'articles/:title', to: 'articles#index'

  # Embedded article GET route
  get ':title', to: 'articles#open_article', as: 'article'
end

解决方案

1. 修正侧边栏链接的Turbo目标

给侧边栏的link_to添加data-turbo-frame属性,指定更新目标为article框架,同时修正链接路径指向articles#index路由,避免跳转到根路径触发整页刷新:

<div class='links padding-top'>
    <%= link_to render(:partial => 'shared/primary_navigation_link', locals: { title: "Getting Started", path: "getting-started" }), articles_path(title: "getting-started"), data: { turbo_frame: "article" } %>
    <%= link_to render(:partial => 'shared/primary_navigation_link', locals: { title: "Types of Charts", path: "types-of-charts" }), articles_path(title: "types-of-charts"), data: { turbo_frame: "article" } %>
</div>

2. 调整控制器逻辑,直接在index方法中加载文章内容

修改articles_controller.rb的index方法,获取当前文章内容并传递给视图,避免通过Turbo Frame的src异步加载:

def index
  target_title = params[:title] || "getting-started"
  file_path = Rails.root.join("app/markdown", "#{target_title}.md").to_s
  @content = ActionController::Base.render inline: GitHub::Markup.render(file_path, File.read(file_path))
end

同时更新articles.html.erb中的Turbo Frame部分,直接渲染内容:

<div class='content'>
    <%= turbo_frame_tag "article" do %>
        <%= @content %>
    <% end %>
</div>

3. 清理路由,避免路径冲突

删除根路径下的get ':title'路由,避免和其他路由冲突,修改后的routes.rb:

Rails.application.routes.draw do
  root :to => redirect('/articles/getting-started')
  get 'articles/:title', to: 'articles#index', as: 'articles'
end

4. 确保导航链接的CSS过渡生效

在primary_navigation_link partial中添加活跃状态判断,给当前选中的链接添加类名:

<% current_title = params[:title] || "getting-started" %>
<div class="nav-link <%= 'active' if current_title == path %>">
    <%= title %>
</div>

然后在CSS中定义过渡效果:

.nav-link {
  transition: color 0.3s ease;
  color: #666;
}

.nav-link.active {
  color: #007bff;
}

核心原理

通过data-turbo-frame属性告诉Turbo仅更新指定的DOM框架,而非整页刷新;同时统一路由和控制器逻辑,确保页面渲染时直接加载目标内容,避免异步加载导致的闪烁问题,最终让CSS过渡效果正常生效。

内容的提问来源于stack exchange,提问作者George B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 13:25:50