新手问题 关于指定页面才使用的 javascript 要怎么组织?

wcc526 · 2014年06月18日 · 最后由 wcc526 回复于 2014年06月18日 · 2866 次阅读

关于指定页面才使用的 javascript 要怎么组织?

有些 javascript 只有在指定页面才会使用,如果合在一起的话,有些函数会造成冲突。比如 document.ready.

我上网找了下以前的做法,发现都是一些 hacker 的方式, https://ruby-china.org/topics/6995 http://brandonhilkert.com/blog/page-specific-javascript-in-rails/

我想问的是 rails 官方有没有提供 javascript 的 best practice 的组织方式?谢谢!

Best practice 就是,除非你指定页面的 Javascript 文件非常非常大,否则都放在 application.js 里面一起打包。

指定页面如果要加大库,比如 Google map, D3 之类,可以用异步载入。其他自有文件都可以在打包里面。

至于函数名冲突,那是你写 JS 的问题。应该改进写法,不能用改变载入的方法解决。

如果你实在要区分页面载入,可以这么写

<%= javascript_tag "foo.js" if controller.name == 'foo' && action == 'index' %>

很难看就是。而且 performance 一般只有轻微劣势,没有优势。

Basecamp 大部分 JavaScript 是这样写的:

<label>
  <b>Set the due date:</b>
  <div data-behavior="date_picker"></div>
</label>
$('[data-behavior~=date_picker]').on 'focus', ->
  $(this).datepicker()

JavaScript 全打包到一个。

http://signalvnoise.com/posts/3167-code-spelunking-in-the-all-new-basecamp

#1 楼 @billy @Rei 我的问题其实不是文件大小的问题,其实是 document.ready 问题,我有个函数需要在B页面刚载入的时候执行。

比如

$ ->
  alert $("#b").val

可是由于这个 js 文件已经被载入过一次了,到了 B 页面就不执行了。需要在这个 B 页面刷新一下,才会执行这个 alert $("#b').val.怎样才能不刷新B页面就能执行这个 alert $("#b").val

谢谢!

@wcc526 哦,知道你碰到的问题了,你用的默认 TurboLinks 吧。这种情况你应该把所有的函数放到一个函数下 面,比如 init(), 然后

$ -> 
  init()

TurbolinkPageTransitionEventWhichIForgetExactMethod ->
  init()

原因是你在 TurboLink 下面转页面时没有 document ready 这个事件,所以你之前写的函数不起作用。

具体 TurboLink event 用法你可以查文档,我好久没用不记得了

如果用的是 Jquery,加上 jquery.turbolinks https://github.com/rails/turbolinks#jqueryturbolinks

Turbolinks 要注意的问题不止 ready 事件,建议完整看一遍文档甚至代码 https://github.com/rails/turbolinks

#4 楼 @billy @Rei 非常感谢两位大神的帮助!

<div id="some-page"></div>
// 用一个自动调用的 function 包起来,就有了自己独立的 context 了
// 这样就算被 assets pipeline 跟其他文件打包压缩成一个文件,也不会互相冲突
(function(){

  $(document).ready(function(){
    // 用 ID 的方式来判断是否是你所想要的页面
    if ($("#some-page").length > 0) {
        // code here
    }
  })

})(window);
需要 登录 后方可回复, 如果你还没有账号请 注册新账号