有渔工具库

介绍 YouYu 对象的用法及机制

Turbolinks

自从升级到 Rails 4 并引入 Turbolinks 之后,JavaScript 代码的执行逻辑发生了重大改变。现结合 Turbolinks 的机制特点将一些注意事项和容易犯的错误指出来,尽量避免发生。

目录

代码执行逻辑的变化

Turbolinks 的引入给原来的代码执行的流程控制带来了毁灭性的冲击……然而,我们要去拥抱变化!

传统的页面加载

引入 Turbolinks 之前,页面的加载是传统的方式——进入新页面,浏览器对 HTML 文档及资源进行加载并解析,会触发 DOMContentLoadedload 等事件。通过 YouYu.prepare()YouYu.ready()YouYu.sandbox() 三个方法就能控制代码的执行顺序。

// 向 YouYu 内部队列中添加函数
// 在调用 YouYu.sandbox() 后立即执行
YouYu.prepare(function() {
  // To do sth.
});

// 向 YouYu 内部队列中添加函数
// 在触发 DOMContentLoaded 后执行
YouYu.ready(function() {
  // To do sth.
});

// 启动封闭的代码执行环境
// 只有调用该方法后通过 YouYu.prepare() 和 YouYu.ready() 添加的函数才会执行
YouYu.sandbox();

Turbolinks 的主要特点就是不更改 <head> 的内容,通过 AJAX 来替换 HTML 文档的 <body>,使页面内容的更新看起来更优雅一些。因此,正常情况下真正的页面加载只有一次,会带来以下问题:

  • 原来的代码执行流程控制已失效;
  • 无法准确地判断当前页面(<body>data-page 属性);
  • 依赖于 <body> 中由 <script> 引入的脚本的代码执行出错;
  • windowdocument 对象是全局唯一的,针对指定页面的操作要避免涉及到这两个对象,例如事件处理,最好是绑定到 <body> 上——$("body").on("click", function() {});

为了使原来的代码适应如此巨大的变化而重写了原来的 YouYu.prepare()YouYu.ready()YouYu.sandbox();添加了 YouYu.inPage() 方法进行指定页面判断;默认引入了 jQuery Turbolinks 解决 jQuery 的 $(document).ready()

新的流程控制逻辑是在触发 DOMContentLoaded 事件或者 page:load 事件时分别先后执行由 YouYu.prepare()YouYu.ready() 添加的函数。简而言之,代码在页面内容加载完成后执行。