How do you create javascript functions that are available project-wide in Ruby on Rails?

前端 未结 7 1528
攒了一身酷
攒了一身酷 2020-12-25 14:05

I put the following function in my application.js:

function test() {
  alert(\"See Me\")
}

classrooms/_new_small.html.haml:



        
相关标签:
7条回答
  • 2020-12-25 14:23

    Simple solution, remove escape_javascript, but it's dangerous see Why escape_javascript before rendering a partial? . Currently you want to execute

    $('#test_container').html("<script>
    //<![CDATA[
     alert('test');
     test();
    //]]>
    </script>
    

    which is converted into

    $('#test_container').html("<script>\n  //<![CDATA[\n    alert(\'test\');\n    test();\n  //]]>\n<\/script>\n");
    

    How do i solve this problem ?

    i will include project_wide.js in app/assets/javascripts/ and then tell application.js to include my file .

    //= require project_wide
    

    Be sure to put the above line after

    //= require jquery
    //= require jquery_ujs
    

    Now, whatever i put in app/assets/javascripts/project_wide.js it will shamelessly appear in whole project except the files which are in public/ folder . In this file, i will put everything which i want to execute .

    Follow common practice

    Currently,you are adding javascript directly inside classrooms/_new_small.html.haml which is uncommon. Mostly , rails developer put such things in assets/javascripts/*.js or call content_for :javascript_custom block in views , which is added in layout file by yield :javascript_custom

    0 讨论(0)
  • 2020-12-25 14:23

    You're probably thinking of the line

    = javascript_include_tag "application"
    

    rather than

    = stylesheet_link_tag 'application', :media => 'all'
    

    If the former is missing, your javascript won't be included.

    0 讨论(0)
  • 2020-12-25 14:37

    I noticed your function test() is indented, which suggests it is nested. If you define a function in the scope of another function, it will not be available outside of it.

    For example this should work, using jQuery:

    function test() { /* do something */ }
    
    // another file or inline script
    
    $(function() {
       test();
    });
    

    But this won't

    (function() {
       function test() {}
    })();
    
    // another file
    
    test(); // undefined
    
    0 讨论(0)
  • 2020-12-25 14:38

    put all those javascript functions in application.js file and include <%= javascript_include_tag 'application' %> in head tag of your layout file

    0 讨论(0)
  • 2020-12-25 14:40

    Assuming you are using asset pipeline & coffeescript: Don't write code in application.js

    In order to keep clean structure, create a folder (eg: application) in app/assets/javascripts

    then require it in your application.js

    //= require jquery
    //= require jquery_ujs
    
    //= require_tree ./application
    

    Create a coffee file (eg: app/assets/javascripts/application/my_feature.js.coffee

    @test = ->
      alert('Hello world')
    

    Coffee output:

    (function() {
    
      this.test = function() {
        return alert('Hello world');
      };
    
    }).call(this);
    

    It's preferable to use namespaces:

    @myGreatFeature =
      test: ->
        alert('Hello world')
    

    or according to the coffeescript FAQ, you could write

    namespace = (target, name, block) ->
      [target, name, block] = [(if typeof exports isnt 'undefined' then exports else window), arguments...] if arguments.length < 3
      top    = target
      target = target[item] or= {} for item in name.split '.'
      block target, top
    
    namespace 'myGreatFeature', (exports) ->
      exports.test = ->
        alert('Hello world')
    

    then you can call myGreatFeature.test() everywhere

    0 讨论(0)
  • 2020-12-25 14:42

    I tried this without an issue. Here's how I did it.

    // application.js

    var test=function(){
      alert("hello");
    }
    

    // in a view, whichever one, i have a content_for :additional_javascripts

    <% content_for :additional_javascripts do %>
      <%= javascript_tag do %>
        test();
      <% end %>
    <% end %>
    

    // in application layout

    <%= javascript_include_tag "application" %>
    <%= yeild(:additional_javascripts) %>
    

    Furthermore, if I want to alert this dynamically later on I could append it to the page and call it then, or put it in a click listener or something.

    I like the syntax var functionName = function(){...} because it properly scopes the method. Also, because of the way javascripts are compiled through the asset pipeline, adding the ; at the end of every executed line is very important.

    This also worked for me as far as loading the script dynamically and calling it from anywhere in the page:

    $("#click_me").live("click", function(){
      $("<script />").text("test();").appendTo("body");
    });
    

    And in the page I had a simple link.

    <a href="#" id="click_me">click</a>
    
    0 讨论(0)
提交回复
热议问题