Хотя # 2 может быть «проще» для вас, как для разработчика, он обеспечивает только сканирование в поисковой системе. И да, если Google обнаружит, что вы обслуживаете другой контент, вы можете быть оштрафованы (я не эксперт в этом, но я слышал об этом).
Как SEO, так и специальные возможности (не только для людей с ограниченными возможностями, но и с помощью мобильных устройств, устройств с сенсорным экраном и других нестандартных платформ с поддержкой компьютеров и Интернета) имеют схожую базовую философию: семантически богатая разметка, которая «доступна» (то есть можно получить доступ, просмотреть, прочитать, обработать или иным образом использовать) для всех этих различных браузеров. Программа чтения с экрана, сканер поисковой системы или пользователь с включенным JavaScript должен уметь без проблем использовать / индексировать / понимать основные функции вашего сайта.
pushState
не добавляет к этому бремени, по моему опыту. Это только выводит то, что раньше было запоздалой мыслью и «если у нас есть время», на передний план веб-разработки.
То, что вы описываете в варианте № 1, обычно является наилучшим способом - но, как и другие проблемы с доступностью и SEO, выполнение этого с pushState
в приложении с большим количеством JavaScript требует предварительного планирования, или оно станет значительным бремя. Он должен быть встроен в страницу и архитектуру приложения с самого начала - модернизация является болезненной и вызовет больше дублирования, чем необходимо.
Я недавно работал с pushState
и SEO для нескольких различных приложений, и я нашел то, что я считаю хорошим подходом. Это в основном соответствует вашему пункту № 1, но не содержит дубликатов html / templates.
Большая часть информации может быть найдена в этих двух сообщениях в блоге:
http://lostechies.com/derickbailey/2011/09/06/test-driving-backbone-views-with-jquery-templates-the-jasmine-gem-and-jasmine-jquery/
и
http://lostechies.com/derickbailey/2011/06/22/rendering-a-rails-partial-as-a-jquery-template/
Суть его в том, что я использую шаблоны ERB или HAML (с запущенными Ruby on Rails, Sinatra и т. Д.) Для рендеринга на стороне сервера и для создания шаблонов на стороне клиента, которые может использовать Backbone, а также для моих Jasmine JavaScript-спецификаций , Это исключает дублирование разметки между серверной и клиентской сторонами.
Оттуда вам нужно предпринять несколько дополнительных шагов, чтобы ваш JavaScript работал с HTML, отображаемым сервером - настоящее прогрессивное улучшение; взять полученную семантическую разметку и улучшить ее с помощью JavaScript.
Например, я создаю приложение галереи изображений с pushState
. Если вы запросите /images/1
с сервера, он отобразит всю галерею изображений на сервере и отправит все HTML, CSS и JavaScript в ваш браузер. Если у вас отключен JavaScript, он будет работать отлично. Каждое ваше действие будет запрашивать другой URL-адрес с сервера, и сервер будет отображать всю разметку для вашего браузера. Однако, если у вас включен JavaScript, JavaScript будет брать уже отредактированный HTML-код вместе с несколькими переменными, сгенерированными сервером, и перехватывать их оттуда.
Вот пример:
<form id="foo">
Name: <input id="name"><button id="say">Say My Name!</button>
</form>
После того, как сервер отобразит это, JavaScript подхватит его (используя представление Backbone.js в этом примере)
FooView = Backbone.View.extend({
events: {
"change #name": "setName",
"click #say": "sayName"
},
setName: function(e){
var name = $(e.currentTarget).val();
this.model.set({name: name});
},
sayName: function(e){
e.preventDefault();
var name = this.model.get("name");
alert("Hello " + name);
},
render: function(){
// do some rendering here, for when this is just running JavaScript
}
});
$(function(){
var model = new MyModel();
var view = new FooView({
model: model,
el: $("#foo")
});
});
Это очень простой пример, но я думаю, что это понятно.
Когда я создаю представление после загрузки страницы, я предоставляю существующее содержимое формы, отрисованной сервером, экземпляру представления как el
для представления. Я не вызываю рендер или имею представление, генерирующее el
для меня, когда загружается первое представление. У меня есть метод рендеринга, доступный после того, как представление запущено и все страницы JavaScript. Это позволяет мне повторно визуализировать вид позже, если мне нужно.
Нажатие кнопки «Скажи мое имя» с включенным JavaScript вызовет окно с предупреждением. Без JavaScript он отправлял обратно на сервер, и сервер мог бы отображать имя в html-элементе где-то.
Редактировать
Рассмотрим более сложный пример, где у вас есть список, который необходимо прикрепить (из комментариев ниже)
Допустим, у вас есть список пользователей в теге <ul>
.Этот список был обработан сервером, когда браузер сделал запрос, и результат выглядит примерно так:
<ul id="user-list">
<li data-id="1">Bob
<li data-id="2">Mary
<li data-id="3">Frank
<li data-id="4">Jane
</ul>
Теперь вам нужно перебрать этот список и прикрепить представление и модель Backbone к каждому из <li>
предметов.С помощью атрибута data-id
вы можете легко найти модель, из которой состоит каждый тег.Затем вам потребуется представление коллекции и элемент, достаточно умное, чтобы присоединиться к этому html.
UserListView = Backbone.View.extend({
attach: function(){
this.el = $("#user-list");
this.$("li").each(function(index){
var userEl = $(this);
var id = userEl.attr("data-id");
var user = this.collection.get(id);
new UserView({
model: user,
el: userEl
});
});
}
});
UserView = Backbone.View.extend({
initialize: function(){
this.model.bind("change:name", this.updateName, this);
},
updateName: function(model, val){
this.el.text(val);
}
});
var userData = {...};
var userList = new UserCollection(userData);
var userListView = new UserListView({collection: userList});
userListView.attach();
В этом примере UserListView
будет перебирать все теги <li>
иприкрепить объект представления с правильной моделью для каждого.он устанавливает обработчик события для события изменения имени модели и обновляет отображаемый текст элемента, когда происходит изменение.
Этот тип процесса, чтобы взять HTML-код, предоставленный сервером, и иметь мойJavaScript вступает во владение и запускает его, это отличный способ добиться успеха в области SEO, доступности и поддержки pushState
.
Надеюсь, это поможет.