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.

На основе комментариев я хотел бы добавить некоторые возможные варианты, чтобы вы начали:

  • JQuery
  • YUI
  • Прототип

Ответ 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, как предлагают другие ответы.