Rails内联Javascript和最佳实践

时间:2009-02-12 22:32:13

标签: javascript ruby-on-rails coding-style

有点使用Rails的新手,我正在开发的应用程序进展顺利 - 不过我正在查看生成的HTML并注意到类似的事情......

<script type="text/javascript">
//<![CDATA[
Droppables.add(...);
//]]>
</script>

围绕HTML,当然与我使用的地方匹配:

<%= drop_receiving_element ... %>

我想知道的是......有更好的方法来做到这一点,还是让它变得更干净?其中一些脚本标签来自部分标签,因此将它们放在“页面底部”并不会对这种情况有所帮助。

另一种选择可能是将所有这些“标记块”推送到一个数组中,然后将它们写在 application.rhtml 文件中,但它仍然有点凌乱......

5 个答案:

答案 0 :(得分:9)

好吧,如果你真的想要使用最佳实践...不要使用内联javascript。保持您的HTML,CSS和Javascript清洁并彼此分离。理想情况下,html文件应该可以在没有CSS和javascript的情况下使用。

最简洁的方法是使用普通的html / css构建你的应用程序,并使用不显眼的javascript来增强它,以提供更好的用户体验。

这种模式是将所有JS文件包含在页面底部,并开始使用onDomReady等功能运行代码。

根据评论,我想添加一些可能的选项来帮助您入门:

  • JQuery的
  • 原型

答案 1 :(得分:4)

最佳做法是删除所有内联JavaScript。但是,我遇到过3个案例,你绝对需要内联javascript:

1。解决图像错误

如果图像标记引用了不存在的图像路径,则防止图像错误出现的唯一方法(即使在Web检查器中)也是这样做的:

<img src="/i/dont/exist.png" onerror="$(this).attr("src", "/i/do/exist.png")" />

以下不起作用,因为在您有时间使用jQuery抓取图像之前执行onerror事件:

$("img").error(function() {
  $(this).attr("src", "/i/do/exist.png")
});

以下代码无效,因为onerror事件未冒泡:

$("img").live("error", function() {
  $(this).attr("src", "/i/do/exist.png");
});

所以你必须使用内联javascript。

2。在页面加载时呈现javascript模板

如果您等到$(document).ready将您的内容Feed绘制到dom中的一个空容器元素中,则用户将看到空白点一瞬间。这就是为什么当您的Twitter页首次加载时,Feed会暂时为空。即使您只是将一个外部脚本文件放在dom的底部,并且在那里您将动态生成的html元素追加到您的页面而不使用$(document).ready,但它仍然为时已晚。您必须在添加容器元素后立即附加动态节点:

<script>App.bootstrap({some: "json"});</script>
<nav id='navigation'></nav>
<header id='header'></header>
<section id='content'>
  // dynamic content here
</section>
<script>App.renderContent();</script>
<aside id='sidebar'>
  // dynamically toggle which one is selected with javascript
  <nav>
    <h3>Search By Category</h3>
    <ol>
      <li>
        <a href="/category-a">Category A</a>
      </li>
      <li>
        <a href="/category-b">Category B</a>
      </li>
    </ol>
  </nav>
</aside>
<script>App.renderSidebar();</script>
<footer id='footer'></footer>

3。您正在使用JSON

引导您的应用

如果您正在使用JSON + javascript模板,最好将第一组数据引导到响应正文中,方法是将其包含在页面中(也在上面的dom示例中)。这使得您不需要额外的ajax请求来呈现内容。

其他一切都应该使用Unobtrusive Javascript

来完成

Rails有很多javascript助手,谢天谢地,在Rails 3中,大多数(全部?)都是不引人注目的;他们现在使用data-属性和外部rails.js文件。然而,那里的许多宝石都是部分红宝石的部分-javascript往往仍然会编写辅助方法添加复杂的javascript内联:

这很有用,但我认为只有一个清晰的自述文件描述如何将javascript添加到application.js更有用。外部javascript使得更容易定制/扩展功能,它可以让您更好地控制系统,并最大限度地减少html页面的重复(因此响应体更小,浏览器可以缓存外部javascript文件)。除非您需要处理丢失的图像,即时渲染或引导某些json,否则您可以将其他所有内容放在外部javascript文件中,而不必使用Rails javascript / ajax帮助程序。

答案 2 :(得分:1)

这困扰了我一段时间,我最终想出了一个双管齐下的方法。

如果您正在为一个封闭域开发一个Web应用程序,搜索引擎性能和JavaScript不是问题,那么只需务实并让Rails的javascript助手做他们的事情。

如果您正在为网络开发,那么请执行Tomh sugested并使用普通的html / css进行编码,然后增强onDomReady。

如果你仍然想使用像使用内联javascript的button_to_remote这样的Rails助手,那么请对你的页面加载处理程序进行编码,以便向服务器发送Ajax请求。然后,您可以使用page.replace / page.replace_html将常规页面元素替换为帮助程序返回的代码。

答案 3 :(得分:1)

我还建议使用不引人注目的Javascript方法并使用jQuery

有关如何使用Rails执行此操作的精彩入门教程,请查看此jQuery + Rails screencast by Ryan Bates

如果你想继续使用jQuery帮助器,那么看看jRails,但如果你这样做,你仍然会违反不引人注目的Javascript前提。

答案 4 :(得分:1)

有时内联JavaScript对于关键的快速视图(例如某些目标网页)或小型片段(例如,Facebook SDK初始化,Analytics / Kissmetrics初始化脚本等)非常有用,其中不使用外部库可以加快页面加载速度。对于这些情况,我建议在布局中使用部分_facebook.js.erb,并定义一个帮助器:

module ApplicationHelper
  def facebook_tag
    content_tag :script, render(partial: 'layouts/facebook.js')
  end
end

然后,使用定义的帮助程序创建文件_facebook.js.erb并在application.html.erb中包含内联JavaScript:

<%= facebook_tag %>

对于任何其他情况,例如您提到内联JavaScript的部分内容,我建议使用不引人注目的JavaScript,如其他答案所示。