在网上看了很多帖子,但最终还是没有找到一个好的解决方案来处理Turbolinks + inline scripts。
Turbolinks 确实给人一种不错的感觉,我真的不想停止使用它,但在某些情况下,我很难调试重复的事件处理程序。
我对内联 javascript 有一些看法:我实际上更喜欢在与之交互的元素附近放置(小的)javascript 代码,只为 app.js 保存大的 javascript 函数。
假设我有一个包含多个过滤器的搜索页面,但仅限于该特定页面。当用户更改搜索过滤器时,应该获取(使用远程/AJAX)新结果。最简单的方法是引入
$(document).on('ready turbolinks:load', function() {
// Submit on every change
$('#myform input').change(function() {
$('#myform').submit()
}
})
当使用 turbolinks 导航并返回到搜索页面时,我自然会在每次选择时遇到多个重复绑定(bind),从而导致多次提交表单。
我试过添加
$('#sidebar-search input').unbind()
就在 .change()
行之前,但它似乎不起作用,并且出于某种原因,该表单仍然发布了几次:一次使用 AJAX,其他几个重复项(谢天谢地已取消)和另一个非远程请求(我的服务器用 HTML 回复)。
使用涡轮链接 5
最佳答案
据我所知,使用内联 JavaScript 时无法避免这个问题。 Turbolinks 自述文件的部分“Working with Script Elements ” 建议避免内联 <script>
s 在安装事件处理程序时:
Turbolinks evaluates
<script>
elements in a page’s<body>
each time it renders the page. You can use inline body scripts to set up per-page JavaScript state or bootstrap client-side models. To install behavior, or to perform more complex operations when the page changes, avoid script elements and use theturbolinks:load
event instead.
听起来您更喜欢内联脚本的原因是将相关的 JS 和 HTML 放在一起很方便。这是工作流程的问题。虽然恐怕我不知道有什么方法可以使单独的 JS 文件像内联 JS 一样方便,但您可以通过在 HTML 中原来是 JS 的地方添加注释来关闭它,说“这个模板有 JS只为它”。在编辑模板时,如果看到该注释,请在编辑器中水平拆分打开相应的 JS 文件,以便同时查看这两个文件。如果您使用的编辑器支持打开文件中的路径,您甚至可以在评论中写下 JS 文件的路径,这样您只需点击链接即可打开它。
您有多种选择来组织单页 JS 片段放入哪些文件。您可以将它们放在每个 Controller 的 JS 文件中,例如 products.js
。 ,或全局文件 application.js
,或者您可以创建一个新的全局文件 single_page_js.js
.然后您可以在每个部分上方放置注释,标记代码影响的模板。或者,您也可以使用某种命名约定将 JS 文件与模板匹配。例如,在为模板 app/views/products/index.html.erb
编写事件处理程序时,您可以将 JS 放在 app/assets/javascripts/products_index.js
中.
最适合您的是某种插件,它可以预处理您的 HTML 模板以删除 <script>
元素,将它们的内容复制到全局 JS 文件,并添加包装代码以确保该 JS 仅在首次访问页面时运行一次。但我不知道有这样的插件。
关于javascript - Rails、turbolinks 和内联 javascript。如何避免重复的事件处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37504587/