#javascript #jquery #ruby-on-rails
#javascript #jquery #ruby-on-rails
Вопрос:
Пробую что-то новое в Ruby — на каждой странице я делаю очень насыщенный материал с помощью jquery. Очевидно, что если я помещу весь jquery в application.js он очень быстро станет очень большим.
Хороший ли это подход к отложенной загрузке js-файла для конкретной страницы в конце? например:
<script>
$(document).ready(function() {
$.getScript("/javascripts/this_pages_scripts.js");
});
</script>
Есть ли способ сделать это на основе rails? Я знаю о новых файлах.js.erb и т.д. и ujs, но я все еще говорю о более специфичных для страницы js — вы знаете, инициализаторах перетаскивания, создателях диалоговых окон и т.д.
Большое вам спасибо.
Комментарии:
1. Когда вы говорите «очень быстро увеличиваться», вы, возможно, преувеличиваете. 20-30 КБ JavaScript — это много, но он не «большой», потому что он может быть отправлен в браузер сжатым примерно до 3 КБ и будет кэшироваться между запросами, если ваш сервер настроен должным образом. Вас должны беспокоить только более крупные библиотеки, такие как jQuery-UI или Google Maps, и не загружать их на страницы, которые их не используют, может помочь.
Ответ №1:
Есть два способа, которые я использую:
Для крошечных, тривиальных скриптов, которые просто добавляют немного привлекательности, я часто включаю их встроенными в шаблон, который они изменяют (точно так же, как вы показали), потому что мне легче отслеживать этот способ.
Для всего, что больше одной или двух маленьких строк, я делаю это незаметно, но загружаю с помощью content_for
Макет моего приложения выглядит следующим образом (в HAML):
= javascript_include_tag 'jquery.144.min','rails','jquery.tools','application'
= yield :scripts
Важная часть заключается в yield :scripts
. Затем на странице, где мне нужен javascript, я делаю:
- content_for :scripts do
= javascript_include_tag 'photo_form'
Это загружает javascript в заголовок, но только в том случае, если показан данный шаблон. content_for
отправляет данные в yield
метод с соответствующим именем.
Подобный блок yield можно вставить куда угодно — у меня также есть такой непосредственно перед закрывающим тегом body. Yield / content_for действительно удобен.
Обратите внимание, как указал тэдман в комментариях, все, что не обязательно загружать в head, должно быть загружено в конце страницы.
И последнее, о чем следует помнить, если у вас есть что-то более сложное, вы также можете использовать переменные экземпляра между вашими шаблонами и представлением вашего приложения. Например, у меня есть панель меню в моем приложении, которая находится в макете приложения. Итак, иногда я хочу вызвать контекстно-зависимую кнопку или дополнительный ряд кнопок только на определенных страницах.
В моем макете приложения я вызываю частичное отображение меню, код меню выглядит следующим образом:
#menubar (normal menu stuff)
- if @special_menu
#special_menu
Итак, тогда в любом шаблоне вы можете сделать:
- @special_menu = true
… и для этой страницы появится указанное меню. Вы также можете сделать это в controller actions, у меня есть один контроллер, где я добавил фильтр before, который устанавливает для одного из флагов меню значение true. Вы могли бы сделать то же самое для любого сложного набора javascript-материалов, которые вы, возможно, захотите включить условно.
Большинство из этих идей я почерпнул из просмотра этого railscast: http://railscasts.com/episodes/30-pretty-page-title
Вам стоит взглянуть!
Комментарии:
1. По возможности файлы JavaScript следует загружать в документе в самом конце, чтобы они не задерживали рендеринг страницы. Аналитика должна быть последней, например, перед закрытием
<body>
тега. jQuery необходимо загружать заранее, как и все остальное, что используется$(document).ready(...)
по очевидным причинам.
Ответ №2:
Установите символ для представления имени файла в вашем заголовке и вызовите его в контроллере
@script = "prototype"
Затем в представлении:
<%= javascript_include_tag @script %>
Или загрузить несколько
@scripts = ["prototype", "dropdown"]
Затем
<% @scripts.each do |s| %>
<%= javascript_include_tag s %>
<% end amp;>
Комментарии:
1. Тогда просто сделайте его другим в каждом контроллере
2. На самом деле это не дает ответа на основную часть вопроса о том, что такое соглашение Rails для структурирования вашего javascript по файлам. И, кстати, вы можете использовать оператор splat для расширения массива до аргументов типа
js = %w{foo bar}; javascript_include_tag *js
.
Ответ №3:
Я лично использую RequireJS и пользовательскую библиотеку обнаружения функций для решения этой проблемы.
Затем у меня есть одна строка для включения скрипта requirejs и его data-main
атрибута на моей странице layout / master / shared view. (Я не знаком с rails как таковым, но это то же самое с любым другим MVC).
Я написал хороший ответ об этом где-то в другом месте. Возможно, вы сможете его найти.