【问题标题】:Rails 5 - turbolinks 5,some JS not loaded on page renderRails 5 - turbolinks 5,页面渲染上未加载一些 JS
【发布时间】:2016-10-14 08:14:47
【问题描述】:

我有一个 Rails 应用程序,我最近更新为 5.0.0.RC1。大部分过渡都很顺利,但我在使用新的 Turbolinks 时遇到了一些问题。例如,在我的应用中,我使用了这个 gem:

gem 'chosen-rails'

我的application.js 文件如下所示:

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require best_in_place
//= require tether
//= require bootstrap
//= require chosen-jquery
//= require_tree .
//= require turbo links

当我单击链接并呈现视图时,我的 chosen-querybest_in_place 也不能正常工作)在初始加载时不起作用,但如果我对页面进行硬刷新,它就会起作用.下面是我得到的结果的图像:

这是我希望它看起来如何的图像:

同样,如果我硬刷新页面,预期的外观会起作用,但不是在常规 redirect_to ... 之后

我的下拉菜单代码如下所示:

= select_tag :screen, options_from_collection_for_select(@screens, "id",  "name"), id: "screen-selection", prompt: "Jump to screen", class: 'form-control  chosen-select', style: "max-width: 250px !important"

redirect_to 之后会生成以下 HTML:

<select name="screen" id="screen-selection" class="form-control chosen-select"  style="max-width: 250px !important">[...]</select>

...在重新加载页面后,我得到了这个:

<select name="screen" id="screen-selection" class="form-control chosen-select"  style="max-width: 250px !important; display: none;">[...]</select>

<div class="chosen-container chosen-container-single" style="width: 190px;" title="" id="screen_selection_chosen"><a class="chosen-single"><span>Jump to screen</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off"></div><ul class="chosen-results"><li class="active-result result-selected" data-option-array-index="0" style="">Jump to screen</li><li class="active-result" data-option-array-index="1" style="">tests</li></ul></div></div>

.coffee 文件中,我尝试像这样初始化chosen

# enable chosen js
$('#screen-selection').chosen({
  width: '190px'
})

关于我做错了什么有什么想法吗?

【问题讨论】:

    标签: javascript jquery ruby-on-rails ruby turbolinks


    【解决方案1】:

    使用 turbolinks,javascript 只加载一次。在硬刷新chosen 工作,因为整个页面被重新渲染。单击链接后,turbolinks 会劫持请求并将其转换为 ajax 请求(而不是整页刷新)。一旦请求进来,turbolinks只替换页面的body,让JS保持原来的状态。

    要解决此问题,您需要像这样将您选择的初始化程序包装在 turbolinks:load 事件中

    $(document).on('turbolinks:load', function() {
      $('#screen-selection').chosen({
        width: '190px'
      })
    })
    

    欲了解更多信息,请参阅https://github.com/turbolinks/turbolinks#installing-javascript-behavior

    【讨论】:

    • 但是有一个很大的问题:turbolinks 将页面存储在缓存中,因此您应该确保您的 javascript 代码是幂等的,否则您最终可能会在页面上有多个选择(或者,在其他情况下,附加到一个元素的几个事件处理程序)。欲了解更多信息,请阅读crossplatform.net/rails/article/should-you-disable-turbolinks/…
    • 几个事件处理程序部分不用担心太多,除非将处理程序附加到文档。否则,至少在 Turbolinks 5 中, 被克隆并恢复,没有任何关联的处理程序等......幸存。
    【解决方案2】:

    这是我使用 Turbolinks 5 和 jQuery 的解决方案:

    1. 安装 gem 'jquery-turbolinks'

    2. 将此 .coffee 文件添加到您的应用中: https://github.com/turbolinks/turbolinks/blob/master/src/turbolinks/compatibility.coffee

    3. 将其命名为 turbolinks-compatibility.coffee

    4. 在 application.js

    //=需要 jquery
    //=需要 jquery_ujs
    //=需要 jquery.turbolinks

    //=需要 turbolinks
    //=需要 turbolinks 兼容性

    【讨论】:

      【解决方案3】:

      找到一种方法让我的所有 javascript 都能正常工作,这让我非常头疼。首先,我按照以下视频尝试使用 gem jquery.turbolinks 的解决方案:How to upgrade to turbolinks 5 但我得到了用于在同一页面中显示图像的灯箱无法正常工作。因此,在一劳永逸地禁用 Turbolinks 之前,我在github 页面上花费了更多时间,然后我试试这个:

      <div data-turbolinks="false">
        <a href="/">Disabled</a>
      </div>
      

      您需要将它放在每个链接上,其中 javascript 需要重新加载页面才能工作。

      也许它不是最好的解决方案,但这可以减轻我的头痛。

      【讨论】:

        【解决方案4】:

        Turbolinks 和 jquery 有点让人头疼。与其在文档就绪时调用操作,不如在 page:load 上更好地工作,因为使用 turbolinks,它不会在您浏览网站时重新加载整个文档。这样的事情可能会奏效:

        $(document).on('page:load', function() {
          $('#screen-selection').chosen({
            width: '190px'
          })
        }
        

        【讨论】:

        • 问题是关于“新的 Turbolinks”(即 Turbolinks 5),它实际上破坏了使用“turbolinks:load”以外的事件的应用程序。因此,您建议的方法不再适用于 Rails 和 Turbolinks 5。
        【解决方案5】:

        我尝试自己解决这个问题,并找到了适合我的解决方案。

        我的问题是我有一个为 cmets 提供“报价”功能的论坛。使用 turbolinks 5,我得到了几个事件侦听器,最终在我的编辑器中获得了来自同一评论的最多四个引号。

        我阅读了幂等性并在这里找到了解决方案:How to make jQuery `bind` or `on` event handlers idempotent

        我创建(实际上是复制)一个全局函数,我在 globals.coffee 文件中用于事件。

        $.fn.event = (name, fn) ->
          @unbind(name).bind name, fn
        

        而且它有效。

        我的函数如下所示:

        $('.quote').event 'click', (event) ->
         do something 
        

        对此的所有信任都归于:Pointy,谁提供了解决方案。

        Link to turbolinks and idempotence

        【讨论】:

          【解决方案6】:

          这就是我的工作.. Turbolinks5 以防止多次加载。

          var ready = function () {
          
             if ($.turboAlreadyLoaded) {
          
                $('#screen-selection').chosen({
                  width: '190px'
                })
             }
          $.turboAlreadyLoaded = true;
          
          }
          $(document).ready(ready);
          $(document).on("turbolinks:load", ready);
          

          【讨论】:

            【解决方案7】:

            我尝试自己解决这个问题,并找到了适合我的解决方案。我也希望对其他人有帮助。

            (function () {
                $('#screen-selection').chosen({
                    width: '190px'
                })
            })();
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-02-19
              相关资源
              最近更新 更多