新手问题 有大神能把 Turbolinks 说得深入浅出点吗?

chairy11 · 2014年03月18日 · 最后由 pynix 回复于 2016年06月30日 · 10818 次阅读

尤其是

$(document).ready ->
  alert "page has loaded!"

要变成

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

什么时候?什么情况?

$(document).ready 每次新进的页面(地址栏回车,跳转)或者 刷新都会执行。

$(document).on "page:change 每次 Turbolinks 工作时执行。

简单的说,一般情况下 ready 函数一般只执行一次,而 page:change 在每次页面切换时都会执行。

$(document).ready ->
  alert "我在 Turbolinks 下只执行一次。"
$(document).on "page:change", ->
  alert "我在 Turbolinks 下每次都执行。"

只要将每次执行的代码和只执行一次的代码分开就可以了。

比如事件委托是发生在 document 上,这个对象只要不刷新就一直存在,所以只执行一遍就可以了

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

然后,比如像每次刷新都要改变 body 颜色的话,就要使用 page:load

$(document).on "page:change", ->
  document.body.style.backgroundColor = '#xxxxx'

另外,page:change 在第一次加载进页面是不会执行的,可以配合 ready 一起使用:

$ ->
$(document).on "page:change", do ->
  document.body.style.backgroundColor = '#xxxxx'
  arguments.callee

弱弱地说我一般都

$ ->
    if $.turbo.isReady == true
        App.Init()

你翻翻 Rei 的博客,里面有篇关于 Turbolink 的写的很易懂

  1. $(document).ready 依赖于 DOMContentLoaded 事件
  2. Turbolinks 接管页面后换页不会产生 DOMContentLoaded,所以换页之后 $(document).ready 无效
  3. Turbolinks 提供了 page:change 取代 $(document).ready

#2 楼 @saiga 现在第一次加载也会触发 page:change 了,所以 page:change 可以替代 $(document).ready

#5 楼 @Rei 总结起来,就是原来所有用

$(document).ready ->

的地方都直接替换成

$(document).on "page:change", ->

就可以了?

Turbolinks 是 pjax 的加强版

pjax 这样理解不知道可不可以:

当你点击“下一页”的时候,网址会变化,比如 page/2,但页面的刷新却是 ajax 风格的:只变化其中一部分,那么点击“下一页”不会触发$(document).ready,而是 page:change

#5 楼 @Rei 你博客打开好慢,我找不着之前那帖子……

#6 楼 @chairy11 要注意 turbolinks 会缓存访问过的页面,缓存 restore 的时候也会触发 page:chang,这样的代码在用户后退的时候会重复绑定:

$(document).on 'page:change', ->
  $('body').on 'click', ->
    console.log('hit')

page:change$().ready 逻辑一样,区别是 turbolinks restore 的时候页面带着之前的状态,而传统页面后退的时候是干净的。

#5 楼 @Rei 记忆中是不会触发的....我去试试

#6 楼 @chairy11 这样替换 99% 会出问题的...

#11 楼 @saiga 我发觉楼主很喜欢把事情简化成一句话理解,这样很不好。

#12 楼 @Rei 真伤我心!我就是希望一切越简单越好啊! #11 楼 @saiga 又伤我心!我希望的结果就是这样替换啊!

#9 楼 @Rei 抓狂,你这样说完,我又彻底蒙了!啥时候用哪个啊?

#14 楼 @chairy11 如果要用 turbolinks,最好就用 page:change,并且要写可以反复执行不冲突的代码。

再扰乱一下楼主,其实我现在用 page:change 很少,换成这样写:

$(document).on 'click', 'body', ->
  console.log('hit')

#17 楼 @Rei 我我我……我再补补 JS 基础吧……

#17 楼 @Rei #11 楼 @saiga 弱弱的问下,用了 turbolinks,那地址栏里的网址一直不变了,head 不变化,GA 统计的 PV 会比实际少? 另外,网址不变,如果想发链接分享给朋友,就很不方便了?

#19 楼 @chairy11

  1. 地址栏会变
  2. head 不变
  3. ga script 如果放在 body 部分,那么跟正常用没什么分别

现在 Ruby China 就是开着 turbolinks 的,你觉得分享链接有困难吗?

#5 楼 @Rei #10 楼 @saiga

知道为啥 page 事件在加载页面时不触发了,原来 我用的不是 page:change 而是 page:load

page:load 事件对应的是 xhr.onload,也就是每次完成 AJAX 请求时触发

page:change 是页面切换调用 changePage触发,然后 Turbolinks 在 installDocumentReadyPageEventTriggers 函数做了处理,所以可以替代 domready 函数!

我去把之前的代码改一下,THK

#20 楼 @Rei 有,地址栏一直显示http://ruby-china.org/,但我想分享的是具体帖子的网址...

#22 楼 @chairy11 那估计是 faye 连接不上出现的 bug,正常状况是不影响的。

#21 楼 @saiga 那什么时候用 load 什么时候用 change ?具体的使用区别?

奥,还有个 page:load,考虑到 restore 的问题,page:load 才是对应 $().ready

the best way is remove it

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