#2は開発者にとって「より簡単」かもしれませんが、検索エンジンのクロールのみを提供します。そして、はい、Googleが提供しているさまざまなコンテンツを見つけた場合、罰せられる可能性があります(私はその専門家ではありませんが、それが起こっていると聞いています)。
SEOとアクセシビリティ(障害者だけでなく、モバイルデバイス、タッチスクリーンデバイス、およびその他の非標準のコンピューティング/インターネット対応プラットフォームを介したアクセシビリティ)は、どちらも同様の基本的な哲学を持っています。これらすべての異なるブラウザでアクセス、表示、読み取り、処理、またはその他の方法で使用されます)。スクリーンリーダー、検索エンジンクローラー、またはJavaScriptを有効にしたユーザーはすべて、問題なくサイトのコア機能を使用/インデックス作成/理解できるはずです。
pushState
私の経験では、この負担は増えません。これは、かつての考えで「時間があれば」というものをWeb開発の最前線にもたらすだけです。
オプション#1で説明することは通常、最善の方法です。ただし、他のアクセシビリティやSEOの問題と同様pushState
に、JavaScriptを多用するアプリでこれを行うには、事前の計画が必要です。そうしないと、大きな負担になります。それは最初からページとアプリケーションアーキテクチャに組み込まれる必要があります-後付けは苦痛であり、必要以上に重複を引き起こします。
私はpushState
最近、いくつかの異なるアプリケーションのためにSEOを使用していて、良いアプローチだと思いました。基本的にはアイテム#1に従いますが、html /テンプレートが重複していないことを示しています。
ほとんどの情報は、次の2つのブログ投稿にあります。
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仕様を作成することです。これにより、サーバー側とクライアント側の間でのマークアップの重複がなくなります。
そこから、サーバーによってレンダリングされたHTMLでJavaScriptを機能させるために、いくつかの追加手順を実行する必要があります。提供されたセマンティックマークアップを取得し、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になった後に使用できるrenderメソッドがあります。これにより、必要に応じて後でビューを再レンダリングできます。
JavaScriptを有効にした状態で[Say My Name]ボタンをクリックすると、警告ボックスが表示されます。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>
次に、このリストをループして、バックボーンビューとモデルを各<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
サポートを実現するための優れた方法です。
お役に立てば幸いです。