javascript - x_sendfile_header - ruby on the rails




Rails 4:如何使用$(document).ready()和turbo-links (13)

我在試圖組織JS文件“rails方式”時遇到了Rails 4應用程序中的一個問題。 他們以前分散在不同的意見。 我將它們組織成單獨的文件並使用資產管道進行編譯。 不過,我剛剛了解到,在啟用turbo鏈接時,jQuery的“ready”事件不會觸發隨後的點擊。 你第一次加載一個頁面它的工作。 但是當你點擊一個鏈接時, ready( function($) {任何內容都不會被執行(因為頁面實際上並沒有再次加載)。

所以我的問題是:什麼是正確的方式來確保jQuery事件正常運行,而渦輪鏈接? 你是否將這些腳本包裝在一個Rails特定的偵聽器中? 或者,也許鐵軌有一些魔法,使它不必要? 這些文檔對於如何工作有些模糊,尤其是在通過像application.js這樣的清單載入多個文件方面。


注意:請參閱@ SDP的答案,以獲得乾淨的內置解決方案

我修正它如下:

請確保在通過更改包含順序包含其他應用程序相關的js文件之前包含application.js,如下所示:

// in application.js - make sure `require_self` comes before `require_tree .`
//= require_self
//= require_tree .

定義一個全局函數來處理application.js的綁定

// application.js
window.onLoad = function(callback) {
  // binds ready event and turbolink page:load event
  $(document).ready(callback);
  $(document).on('page:load',callback);
};

現在你可以綁定像這樣的東西:

// in coffee script:
onLoad ->
  $('a.clickable').click => 
    alert('link clicked!');

// equivalent in javascript:
onLoad(function() {
  $('a.clickable').click(function() {
    alert('link clicked');
});

不是使用變量來保存“就緒”函數並將其綁定到事件,而是可以在page:load觸發器時觸發ready事件。

$(document).on('page:load', function() {
  $(document).trigger('ready');
});

以下是我所做的確保事情不會被執行兩次:

$(document).on("page:change", function() {
     // ... init things, just do not bind events ...
     $(document).off("page:change");
});

我發現使用jquery-turbolinks gem或者使用$(document).ready$(document).on("page:load")或使用$(document).on("page:change")本身的行為意外 -特別是如果你在開發中。


你必須使用:

document.addEventListener("turbolinks:load", function() {
  // your code here
})

來自turbolinks doc


我剛剛了解到解決這個問題的另一種選擇。 如果您加載jquery-turbolinks gem,它會將Rails Turbolinks事件綁定到document.ready事件,以便以通常的方式編寫jQuery。 您只需在js清單文件中的jquery後面添加jquery.turbolinks (默認情況下為application.js )。


我想我會在這里為那些升級到github.com/turbolinks/turbolinks人留下這個:解決你的代碼最簡單的方法是從:

var ready;
ready = function() {
  // Your JS here
}
$(document).ready(ready);
$(document).on('page:load', ready)

至:

var ready;
ready = function() {
  // Your JS here
}
$(document).on('turbolinks:load', ready);

參考: https://github.com/turbolinks/turbolinks/issues/9#issuecomment-184717346https://github.com/turbolinks/turbolinks/issues/9#issuecomment-184717346


我通常為我的rails 4項目執行以下操作:

application.js

function onInit(callback){
    $(document).ready(callback);
    $(document).on('page:load', callback);
}

然後在.js文件的其餘部分,而不是使用$(function (){})我調用onInit(function(){})


最近我發現了最簡單易懂的處理方式:

$(document).on 'ready page:load', ->
  # Actions to do

要么

$(document).on('ready page:load', function () {
  // Actions to do
});

編輯
如果已將委託事件綁定到document ,請確保將它們附加到ready函數之外,否則它們會在每個page:load上反彈page:load事件(導致多次運行相同的函數)。 例如,如果您有任何類似的電話:

$(document).on 'ready page:load', ->
  ...
  $(document).on 'click', '.button', ->
    ...
  ...

把它們從ready函數中拿出來,像這樣:

$(document).on 'ready page:load', ->
  ...
  ...

$(document).on 'click', '.button', ->
  ...

綁定到document委託事件不需要綁定在ready事件上。


經過測試的解決方案終於來到了這個。 這很多你的代碼絕對不會被調用兩次。

      var has_loaded=false;
      var ready = function() {
        if(!has_loaded){
          has_loaded=true;
           
          // YOURJS here
        }
      }

      $(document).ready(ready);
      $(document).bind('page:change', ready);



首先,安裝jquery-turbolinks寶石。 然後,不要忘記將您包含的Javascript文件從application.html.erb正文的結尾移至其<head>

如此處所述 ,如果您為了速度優化原因而將應用程序JavaScript鏈接放在頁腳中,則需要將其移至標記中,以便在標記中的內容之前加載它。 這個解決方案為我工作。


 <%= link_to 'Edit', edit_article_path(article), 'data-no-turbolink' => true %>

也許你可以像這樣使用“準備好”,就像關閉你的turbolink。


$(document).ready(ready)  

$(document).on('turbolinks:load', ready)




turbolinks