Rails 4: how to use $(document).ready() with turbo-links

前端 未结 19 1564
忘了有多久
忘了有多久 2020-11-21 06:52

I ran into an issue in my Rails 4 app while trying to organize JS files \"the rails way\". They were previously scattered across different views. I organized them into separ

相关标签:
19条回答
  • 2020-11-21 07:47

    Found this in the Rails 4 documentation, similar to DemoZluk's solution but slightly shorter:

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

    OR

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

    If you have external scripts that call $(document).ready() or if you can't be bothered rewriting all your existing JavaScript, then this gem allows you to keep using $(document).ready() with TurboLinks: https://github.com/kossnocorp/jquery.turbolinks

    0 讨论(0)
  • 2020-11-21 07:47

    NOTE: See @SDP's answer for a clean, built-in solution

    I fixed it as follows:

    make sure you include application.js before the other app dependent js files get included by changing the include order as follows:

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

    Define a global function that handles the binding in application.js

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

    Now you can bind stuff like:

    // in coffee script:
    onLoad ->
      $('a.clickable').click => 
        alert('link clicked!');
    
    // equivalent in javascript:
    onLoad(function() {
      $('a.clickable').click(function() {
        alert('link clicked');
    });
    
    0 讨论(0)
  • 2020-11-21 07:49

    I usually do the following for my rails 4 projects:

    In application.js

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

    Then in the rest of the .js files, instead of using $(function (){}) I call onInit(function(){})

    0 讨论(0)
  • 2020-11-21 07:50

    Here's what I have done to ensure things aren't executed twice:

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

    I find using the jquery-turbolinks gem or combining $(document).ready and $(document).on("page:load") or using $(document).on("page:change") by itself behaves unexpectedly--especially if you're in development.

    0 讨论(0)
  • 2020-11-21 07:51

    As per the new rails guides, the correct way is to do the following:

    $(document).on('turbolinks:load', function() {
       console.log('(document).turbolinks:load')
    });
    

    or, in coffeescript:

    $(document).on "turbolinks:load", ->
    alert "page has loaded!"
    

    Do not listen to the event $(document).ready and only one event will be fired. No surprises, no need to use the jquery.turbolinks gem.

    This works with rails 4.2 and above, not only rails 5.

    0 讨论(0)
  • 2020-11-21 07:53

    Recently I found the most clean and easy to understand way of dealing with it:

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

    OR

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

    EDIT
    If you have delegated events bound to the document, make sure you attach them outside of the ready function, otherwise they will get rebound on every page:load event (causing the same functions to be run multiple times). For example, if you have any calls like this:

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

    Take them out of the ready function, like this:

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

    Delegated events bound to the document do not need to be bound on the ready event.

    0 讨论(0)
提交回复
热议问题