【问题标题】:You are loading Turbolinks from a <script> element inside the <body> element - leads to duplicated elements in the view您正在从 <body> 元素内的 <script> 元素加载 Turbolinks - 导致视图中的元素重复
【发布时间】:2020-08-14 07:17:40
【问题描述】:

我遇到了一个非常奇怪的问题。我昨天在我的 Rails 应用程序(Algolia Places)中为我的表单添加了一个自动完成选项。我还安装了 webpacker,以使用我的应用程序中的包。因此,结果表明,在我的 address.html.erb 中,我现在得到了两个显示在彼此下方的表单:一个带有自动完成功能,另一个没有。见下图(第一个表格有自动完成地址,下面那个没有)。

我认为问题出在我的 application.html.erb 中,现在的代码如下所示:

<!DOCTYPE html>
<html>
  <head>
    <title>Neigbornow</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <meta>

      <%= yield %>
      <%= javascript_include_tag 'application' %>
      <%= javascript_pack_tag 'application' %>
      <%= javascript_pack_tag 'autocomplete' %>
    </meta>
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>

    <% if @user.nil? %>
      <%= render 'layouts/header' %>
    <% elsif user_signed_in? && current_page?(user_step_path) || %>
      <%= render partial: "layouts/header_address" %>
    <% else %>
      <%= render 'layouts/header_rest' %>
    <% end %>
      <%= render 'layouts/flash' %>
    <%= yield %>
  </body>
</html>

控制台抛出以下错误:

You are loading Turbolinks from a <script> element inside the <body> element. This is probably not what you meant to do!

Load your application’s JavaScript bundle inside the <head> element instead. <script> elements in <body> are evaluated with each page change.

For more information, see: https://github.com/turbolinks/turbolinks#working-with-script-elements

——
Suppress this warning by adding a `data-turbolinks-suppress-warning` attribute to: <script src="/assets/turbolinks.self-569ee74eaa15c1e2019317ff770b8769b1ec033a0f572a485f64c82ddc8f989e.js?body=1"></script>

如果我改变了

<%= yield %>

<%= yield :js %>

第二种形式消失了,但自动完成功能也消失了。如果我移动,也会发生同样的情况

<%= yield %>

到最后。这对我来说是一个谜。我真的需要这方面的帮助,因为互联网上没有这方面的材料。

附: 这是布局/标题

<nav class="navbar navbar-inverse navbar-fixed-top">
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <div class="navbar-brand pull-left" href="#">
        <img src="<%= image_path('logo_transparent.png') %>" width="147" height="70" class="d-inline-block align-left mr-2">
      </div>
    </div>
    <div class="navbar-collapse collapse">

        <ul class="nav navbar-nav pull-right">
          <li><%= link_to 'Home', root_path, method: :get %></li>
          <li><a>About</a></li>
          <li><a>Search</a></li>
          <li><a>Contact</a>

          <% if user_signed_in? %>
            <% if current_user.profile == nil %>
              <li><span class="bg-primary text-white rounded"><%= link_to 'Create profile', new_user_profile_path(current_user.id) %></span></li>
            <% else %>
              <li><span class="bg-primary text-white rounded"><%= link_to 'My profile', user_profile_path(@user) %></span></li>
            <% end %>

          <li><span class="bg-primary text-white rounded"><%= link_to 'Log out', destroy_user_session_path, method: :delete %></span></li>

        <% else %>
          <li><div class="log-in-btn"><button class="btn" type="submit"><%= link_to 'Log in', new_user_session_path %></button></div></li>
        <% end %>
        </ul>

    </div> <!--/.nav-collapse -->
  </div>

但我实际上在此页面上呈现另一个标题 - 一个空的,如您所见

<nav class="navbar navbar-inverse navbar-fixed-top">
  <div class="container">
    <div class="navbar-header">
      <div class="navbar-brand pull-left" href="#">
        <img src="<%= image_path('logo_transparent.png') %>" width="147" height="70" class="d-inline-block align-left mr-2">
      </div>
    </div>
  </div>
</nav>

在首页,没有自动填充功能,这个问题不会出现。

附: - 编辑版本

<!DOCTYPE html>
<html>
  <head>
    <title>Neigbornow</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <%= yield :meta %>
    <%= yield %>
    <%= javascript_include_tag 'application' %>
    <%= javascript_pack_tag 'application' %>
    <%= javascript_pack_tag 'autocomplete' %>
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
     <%= yield :css %>

  </head>
  <body>
    <% if @user.nil? %>
      <%= render 'layouts/header' %>
    <% elsif user_signed_in? && current_page?(user_step_path) || %>
      <%= render partial: "layouts/header_address" %>
    <% else %>
      <%= render 'layouts/header_rest' %>
    <% end %>
      <%= render 'layouts/flash' %>
    <!- I would really recommend that you wrap this in an element -!>
    <div id="main">
    </div>
  </body>
</html>

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    首先使用这样的元标记是完全无效的。 meta tag 是一个空元素,因此永远不会有结束标记或内容。

    这些是元标记的有效示例:

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta property="og:url" content="http://www.nytimes.com/2015/02/19/arts/international/when-great-minds-dont-think-alike.html" />
    <meta property="og:type" content="article" />
    

    其次,您的布局中有两个“未命名的产量”。您的布局应该只包含一个未命名的产量,因为正在渲染的模板被实际注入。在这种情况下,内容被注入了两次,当浏览器进入完全 slop 模式时,您会得到一个完全损坏的文档和错误。

    turbolinks 警告您“您正在从 body 元素内的脚本元素加载 Turbolinks”的原因。就是前面提到的slop模式。您正在注入&lt;head&gt; 标记中不允许的一堆元素,并且浏览器试图通过添加&lt;body&gt; 标记来理解垃圾HTML。

    您删除第二个产量的解决方案实际上是完全疯狂的。它根本不是你想要的。您的视图不应呈现在页面的 &lt;head&gt; 元素内。那是完全无效的 HTML,并且会导致一个完全不正确的文档,其行为将非常不可预测。

    如果您想让正在渲染的模板将内容注入布局(“框外”),则可以在布局中包含多个命名收益。

    <!DOCTYPE html>
    <html>
      <head>
        <title>Neigbornow</title>
        <%= csrf_meta_tags %>
        <%= csp_meta_tag %>
        <%= yield :meta %>
        <%= javascript_include_tag 'application' %>
        <%= javascript_pack_tag 'application' %>
        <%= javascript_pack_tag 'autocomplete' %>
        <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
        <%= yield :js %>
        <%= yield :css %>
      </head>
      <body>
        <% if @user.nil? %>
          <%= render 'layouts/header' %>
        <% elsif user_signed_in? && current_page?(user_step_path) || %>
          <%= render partial: "layouts/header_address" %>
        <% else %>
          <%= render 'layouts/header_rest' %>
        <% end %>
          <%= render 'layouts/flash' %>
        <!- I would really recommend that you wrap this in an element -!>
        <div id="main">
          <%= yield %>
        </div>
      </body>
    </html>
    

    然后您可以使用content_for 从视图中为命名收益提供内容:

    <h1><%= @article.title %></h1>
    
    <% content_for :meta do %>
      <meta property="og:title" content="<%= @article.title %>" />
    <% end %>
    

    见:

    【讨论】:

    • 非常感谢您抽出宝贵的时间,这对我来说完全有意义,但是,如果我这样做,如上所述,那么我的自动完成功能就会消失
    • 它一直显示这个错误:错误:Algolia Places: 'container' must point to an 元素。我对此进行了研究,但解决方案是更改 QuerySlector,不幸的是,这并没有解决问题。
    • 请看上面的 P.S. - 编辑版,这也是一种不好的方法吗?这样就可以了
    • 不,仍然完全错误。您的主要yield 应该在文档的&lt;body&gt; 标记中。无处。仅仅因为它恰好使您遇到的任何直接错误保持沉默并不意味着它是一个好主意。尝试在生成的标记上使用 HTML5 验证器,您会发现这是一个非常糟糕的主意。
    • 您为什么不问您应该如何实际集成自动完成功能并提供相关信息?
    【解决方案2】:

    我认为这是因为您有两个 yield 语句。我想你不需要 &lt;meta&gt; 标签里面的那个?

    meta 标记内的yield 在包含 javascript 之前加载表单。这可能是第一个表单没有自动完成功能的原因。

    【讨论】:

    • 真的!但是删除 meta 中的那个破坏了我的自动完成功能。所以我删除了正文中的那个,现在它可以工作了。非常感谢!
    • 这听起来更像是会破坏您应用程序中的所有其他内容。
    • meta 标记中包含表单的yield 似乎不正确。您可能需要重新考虑。
    【解决方案3】:

    只需将您的 javascript 和样式表标签助手放在 csrf_meta_tags 和 csp_meta_tag 之前:

    <head>
    <title>Neigbornow</title>
    
    <%= javascript_include_tag 'application' %>
    <%= javascript_pack_tag 'application' %>
    <%= javascript_pack_tag 'autocomplete' %>
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    
    </head>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-23
      • 1970-01-01
      • 2010-12-15
      • 2021-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多