Rails встроенный Javascript и лучшие практики
Я немного новичок в использовании Rails, и приложение, над которым я работаю, идет хорошо, но я ищу, хотя сгенерированный HTML и заметил такие вещи, как...
<script type="text/javascript">
//<![CDATA[
Droppables.add(...);
//]]>
</script>
Посыпать вокруг HTML, который, конечно, совпадает с местами, где я использую:
<%= drop_receiving_element ... %>
Мне интересно, есть ли лучший способ сделать это или сделать его более чистым? Некоторые из этих тегов script поступают из частичных файлов, поэтому их размещение в нижней части страницы в действительности не помогает.
Другая опция может выталкивать все эти "блоки тегов" в массив, а затем записывать их в файл application.rhtml, но все еще немного беспорядочно...
Ответы
Ответ 1
Ну, если вы действительно хотите использовать лучшие практики... Не используйте встроенный javascript. Храните свой HTML, CSS и Javascript в чистоте и отделяйте друг от друга. В идеале html файл должен использоваться без CSS и javascript.
Самый чистый способ, imo, - просто создать ваше приложение, используя простой html/css, и улучшить его с ненавязчивым javascript, чтобы обеспечить лучший пользовательский интерфейс.
Образец для этого состоит в том, чтобы включить все ваши JS файлы в нижней части страницы и запустить ваш код с такими функциями, как onDomReady.
На основе комментариев я хотел бы добавить некоторые возможные варианты, чтобы вы начали:
Ответ 2
Лучшей практикой является удаление всех встроенных javascript. Тем не менее, есть три случая, с которыми я столкнулся, где вам абсолютно необходим встроенный javascript:
1. Чтобы устранить ошибки изображения
Если тег изображения ссылается на путь изображения, которого не существует, единственный способ предотвратить появление ошибки изображения (даже в веб-инспекторе) заключается в следующем:
<img src="/i/dont/exist.png" onerror="$(this).attr("src", "/i/do/exist.png")" />
Следующее не работает, потому что событие onerror
выполняется до того, как вы даже успеете захватить изображение с помощью jQuery:
$("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
, чтобы нарисовать фид содержимого в один из пустых элементов контейнера в вашем доме, пользователь увидит пустое место в течение секунды. Поэтому, когда ваша страница Twitter загружается первой, фид пуст на мгновение. Даже если вы просто поместите внешний script файл в нижней части 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-шаблоны, неплохо было бы загрузить первый набор данных в тело ответа, включив его в строку на странице (также в примере выше). Это делает так, что вам не нужен дополнительный запрос ajax для рендеринга контента.
Все остальное должно быть сделано с помощью ненавязчивого Javascript
В Rails есть много помощников javascript, и, к счастью, в Rails 3 большинство (всего?) его ненавязчиво; теперь они используют атрибут data-
и внешний rails.js
файл. Тем не менее, многие из драгоценных камней, которые являются частью ruby part-javascript, как правило, продолжают писать вспомогательные методы, добавляют сложный javascript inline:
Это полезно, но я думаю, что просто наличие четкого README, описывающего, как добавить javascript в ваш application.js
, еще более полезно. Внешний javascript значительно упрощает настройку/расширение функциональности по дороге, это дает вам намного больше контроля над системой и минимизирует дублирование на ваших html-страницах (так что тело ответа меньше, и браузер может кэшировать внешние файлы javascript). Если вам не нужно обрабатывать недостающие изображения, мгновенный рендеринг или загрузку некоторого json, вы можете поместить все остальное в внешние файлы javascript и никогда не использовать Rails javascript/ajax-помощники.
Ответ 3
Это беспокоило меня какое-то время, и я в конце концов придумал два подхода.
Если вы разрабатываете веб-приложение для закрытого домена, где производительность поискового сервера и javascript не являются проблемой, просто будьте прагматичны и пусть помощники javascript Rails делают свое дело.
Если вы разрабатываете для Интернета в целом, то делайте то, что Tomh запустил и закодировал в простой html/css, а затем улучшил onDomReady.
Если вы все еще хотите использовать помощники Rails, такие как button_to_remote, которые используют встроенный javascript, затем закодируйте обработчик загрузки страницы для отправки запроса Ajax на сервер. вы можете затем использовать page.replace/page.replace_html, чтобы заменить обычные элементы страницы кодом, возвращаемым с помощью хелперов.
Ответ 4
Я бы также рекомендовал использовать ненавязчивый подход Javascript и использовать jQuery.
Для большого вводного учебника о том, как это сделать с Rails, посмотрите на этот jQuery + Rails screencast от Райана Бейтса.
Если вы хотите использовать помощники с jQuery, взгляните на jRails, но если вы это сделаете, вы по-прежнему будете нарушать ненавязчивое предположение Javascript.
Ответ 5
Иногда встроенный JavaScript полезен для критических, быстрых просмотров (например, определенных целевых страниц) или небольших фрагментов (например, инициализация SDK в Facebook, сценарии инициализации Analytics/Kissmetrics и т.д.), где использование внешних библиотек может ускорить загрузку страницы, В этих случаях я рекомендую использовать частичный макет _facebook.js.erb внутри макетов и определить помощника:
module ApplicationHelper
def facebook_tag
content_tag :script, render(partial: 'layouts/facebook.js')
end
end
Затем создайте файл _facebook.js.erb и включите встроенный JavaScript внутри application.html.erb с помощью определенного помощника:
<%= facebook_tag %>
Для любого другого случая, такого как частичные, о которых вы упоминаете, встроенный JavaScript, я рекомендую использовать ненавязчивый JavaScript, как предлагают другие ответы.