据我所知,出于性能原因,最好让资产管道连接并缩小我的所有javascript并将整个页面请求发送给每个页面。这很公平
然而,我的一堆javascript就像将特定行为绑定到特定页面元素之类的东西 - 比如
$('button').click(function(e) { $('input.sel').val(this.name); }
如果我知道这个代码只在那个页面上执行,我会感觉更舒服 - 而不是在其他页面上可能巧合地使用相同ID或匹配相同选择器的元素如何处理这个?
我宁愿不把所有这些东西都放在元素内联中,只是因为当它长度超过两行时,保持javascript正确缩进到.html.erb文件中是比它需要更多的工作
答案 0 :(得分:17)
这是我做的(基于一些stackoverflow答案):
application_helper.rb
def body_page_name
[controller_name.classify.pluralize, action_name.classify].join
end
application.html.haml
%body{data: {page: body_page_name}}
的application.js
$(function() {
var page = $("body").data("page");
if("object" === typeof window[page])
window[page].init();
});
在适当的js文件中有一个名为ControllerAction的对象:
tickets.js
var TicketsShow = new function() {
var self = this;
self.init = function() {
// code which may call other functions in self
};
};
可能有更好的方法,但这对我有用
答案 1 :(得分:4)
我将描述我目前正在做的事情,以防它给任何人一个更好的主意
1)我更改了application.html.erb中的'body'标签,将当前控制器和操作添加为data- attributes
<body data-controller="<%= controller.controller_name %>"
data-action="<%= controller.action_name %>" >
2)我在相关的javascript
的顶部测试了这个$(document).ready(function() {
if($('body').data('controller')=='stories') {
$('.story').click(function(e) {
var u=$(this).data('url');
u && (document.location=u);
});
}
});
我无法决定我是否认为这是一个好主意
答案 2 :(得分:1)
对于特定于页面的JavaScript,我通常会执行以下操作:
在应用程序助手中,我创建了一个类属性(尽管你也可以使用数据属性)。
module ApplicationHelper
def body_attributes
controller = params[:controller].gsub('/', ' ')
action = params[:action]
version = @version ? "version_#{@version}" : nil
{
class: ([controller, action, version] - [nil]).join(' ')
}
end
end
注意我还添加了一个版本字符串。这有助于Google内容实验,并使A / B测试变得轻而易举。
在我的全局布局文件中,我做了类似的操作,在body标签上插入属性:
!!! 5
%html
%head
...
%body{body_attributes}
现在在我的页面特定脚本中,我只检查类属性,如下所示:
$(function () {
if ($('body.pledge.new, body.pledge.create').length > 0) {
// do work here...
}
});
这种方法的优点是可以非常快速地获得身体。条件中的脚本根本不会在我选择的页面之外的任何页面上执行,因此开销最小,而且我不需要在整个代码中更改选择器。
请注意,这个答案现在已经有3年了。您应该使用像React这样的框架来使用客户端路由。
答案 3 :(得分:0)
我会在BODY标记中添加一个类,允许您识别每个页面,从而确定每页的每个控件。
<body class='page1'>
JS:
$('.page1 button').click(function(e) { $('input.sel').val(this.name); }
答案 4 :(得分:0)
我已经完成了它并且看到它以几种不同的方式完成:
装配mvc以便能够每页加载一个特定的js文件,命名方式与控制器文件相同。喜欢:<controller-name>.js
在JS中创建一个url解析器,然后将一个全局变量设置为当前页面:UrlParams.currentView = 'dashboard';
然后说if(UrlParams.currentView == 'dashboard') { //do specific js here }
将唯一标识符设置为页面类或ID,然后使用JS选择器进行定位。 $('#dashboard').xyz();