您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 网站教程 > AJAX教程 >
    Coffee script & Javascript 结构与组织
    时间:2016-07-14 20:58 来源: 作者: 浏览:收藏 挑错 推荐 打印

    Title: Coffee script & script organize
    Tags: coffeescript,javascript
    Slug: coffeescript
    Excerpt: rails coffee script
    Date: 2012-09-25

    CofeeScript & JavaScript Organize

    我需要解决以下问题,相信其它朋友也会碰到,这是我翻查的结果,结论已经在我的项目用了,感觉不错,分享一下。原博文在 

    Target

    • 所有js compile在一个js,不论是否需要
    • 不同页面需要运行的js才运行,不需要的不运行

    Solution 1

    init不同namespace的js

    application.html.erb 这段不能用coffee script,原因是动态call init的方法
    可以再细分按action name或用正则表达式

    :javascript
      $(function() {
        #{"Window.#{params[:controller]}"}.init();
      });
    

    转换成的代码,当在访问 /apples

    Window.apples.init()
    

    对应的 apples.js.coffeelike只是为了demo,可以用ujs代替

    Window.apples =
      like: (id) ->
            console.log("like apple:" + id)
            return
      init: () -> 
            console.log("init apple") 
            $(".apple").click () ->
              console.log("click me")
              console.log( $(this).attr("id") )
              Window.apples.like($(this).attr("id"))
              return
            return
    

    oranges.js.coffee

     oranges =
      init: () -> 
            console.log("init orange") 
            return
      eat: (id) ->
            console.log("eat orange:" + id)
            return
    

    当访问 /apples 时,只会init apples的js,如果是/oranges,则只会init orange js

    Solution 2

    方案1的变形,不过组织起来更舒服一占o,与方法1差不多

    common.js.coffee 将 apples, oranges 等作为namespace

    Window.FruitsSite = 
      common: 
        init: () -> 
          console.log("init common")
      apples: 
        init: ()-> 
          console.log("init apples")
        like: (id) ->
          console.log("like apple id: " + id)
      oranges:
        init: () -> 
          console.log("init oranges")
        eat: (id) ->
          console.log("eat orange id: " + id)
    

    application.haml 动态按controller名去调用

    Window.FruitsSite["#{params[:controller]}"].init();
    

    Solution 3

    方案2的变形,将需要用到的 js 类放到 body中,同时细分到不同action页面级别

    <body data-controller="apples" data-action="index"">
    找出对应 apples 的 index 页面需要init的东西init一下

    <body data-js="apples autoscroll"> Iint apples 和 autoscroll

    查找一下data-js,然后找出对应的模块init一下就好

    例子

    apples.js.coffee

    Window.FruitsSite = 
      apples: 
        index: 
          init: () ->
            console.log("init apples index page")
            return
    

    applicatoin.haml 其实就是多一个层级而已,另外就是可以将这下面这段代码转成coffee script,不用像上面两个例子写一些恶心js在页面上

     var $body = $("body");
     var controller = $body.attr("data-controller");
     var action = $body.attr("data-action");
     Window.FruitsSite[controller][action].init();
    

    Solution 4

    重写 jquery ready方法,利用body class 调用对应的ready

    重写jquery ready方法,看不明proxy的那个方法,不过没关系
    这段代码来自于 

    (function ($) {
       console.log("try to reset the ready function");
       var ready = $.fn.ready;
       $.fn.ready = function (fn) {
         console.log(this);
         console.log("Context:" + this.context);
         console.log(this.context);
         if (this.context === undefined) {
           console.log("no context defined");
           // The $().ready(fn) case.
           ready(fn);
         } else if (this.selector) {
           console.log("Selector:" + this.selector);
           ready($.proxy(function(){
             $(this.selector, this.context).each(fn);
           }, this));
         } else {
           console.log("Context have but no selector");
           ready($.proxy(function(){
             $(this).each(fn);
           }, this));
         }
       }
     })();
    

    写不同的ready函数

    $('.apples.index').ready(function () {
       console.log("apple index page init");
     });
    $('.oranges.index').ready(function(){
       console.log("oranges index page init");
     });
    

    ready这个方法就可有可无了

    $(function() {
    });
    

    body中的class一定要以空间分隔

    %body{:class => "#{params[:controller]} #{params[:action]}"}
    

    其它的方法还有

    用条件语句去控制,只是不那么高明

    $(body).hasClass("autoscroll")
    

    只当需要时才new instance

    Window.FruitsSite.apples = new Apples;

    只能先实例化

    创建实例

    class Apples
      index:
        init: () ->
          console.log("init apples index page")
          return
    console.log(window.FruitsSite)
    window.FruitsSite.apples = new Apples
    

    简版

    window.FruitsSite.apples = 
      index:
        init: () ->
          console.log("init apples index page")
          return
    console.log(window.FruitsSite)
    

    CoffeeScript 整合 vim

    到  下载一下pkg(Mac)
    装完后

    sudo npm install -g coffee-script
    
    
    
    mkdir -p ~/.vim/autoload ~/.vim/bundle 
    curl 'www.vim.org/scripts/download_script.?src_id=16224' 
      > ~/.vim/autoload/pathogen.vim
    

    修改一下 ~/.vimrc

    filetype plugin indent on
    call pathogen#infect()
    

    安装 vim plugin

     cd ~/.vim/bundle
     git clone https://github.com/kchmck/vim-coffee-script.git
     cd ~/.vim/bundle/vim-coffee-script
     git pull
    

    人肉安装(可选方法)

     unzip -od ~/.vim vim-coffee-script-HASH.zip
    

    用vim打开一个coffee script 文件

    命令行,就可以将coffee script 转成js分屏显示,爽啊

    :CoffeeCompile
    

    Reference

    (责任编辑:12图资源库)