ExtJSとMootoolsに基づいたRIAアプリケーションでのURIフラグメントアドレス指定の使用

URIフラグメント(フラグメント識別子、ハッシュ、ブックマーク、アンカー)は、さまざまなインターフェイス要素とアプリケーションステータスへの直接リンクを指定する便利な方法として、インタラクティブWebアプリケーションで最近積極的に使用されるようになりました。 フラグメントアドレス指定の最も顕著な例は、GMailです。 お気づきかもしれませんが、受信トレイ、送信済み、下書きフォルダには、#inbox、#sent、#draftsで終わるリンクがあります。 それらの間の遷移はページ全体をリロードしません(文字のリストのみが更新されます)が、同時に、それぞれを別々のウィンドウ/タブで開くと、すぐに探しているページに到達します。



この記事では、JavaScriptを使用したこのような便利なナビゲーションメカニズムの実装について説明します。



どうだった...




従来のHTMLでは、URIフラグメントを使用して、大きなドキュメント内で簡単なナビゲーションを作成しました。 ドキュメントの適切な場所に、フォームのタグ(いわゆるアンカー)を挿入し、Go Hereタイプのリンクを使用してそれらを参照できます。 このようなリンクをクリックすると、ブラウザはページをリロードせずにドキュメントを適切な場所にスクロールしました。 新しいウィンドウでsite.com/path/to/doc.html#go-hereリンクを開くことも可能で、ドキュメントをロードした後、ブラウザはアンカー位置から自動的にそれを表示しました。 当然、アンカーはこの機能をサポートするブラウザでのみ機能しました。 フラグメントの処理は、完全かつ完全にクライアント側に移行しました。 URIフラグメントはWebサーバーにも送信されませんでした(現在は送信されていません)。



...そして今




ご覧のとおり、フラグメントには2つの重要な利点があります。





今日、DHTMLおよびAJAXテクノロジーの勝利の行進の時代に、フラグメントはこれらの2つの注目すべき特性のおかげで新しい命を獲得しました。 URIフラグメントのアドレス指定により、ページをリロードすることなく、AJAXで完全に動作するRIAアプリケーションを構築でき、同時に通常のWebアプリケーションの通常の機能の一部を保持できます。 つまり、リンクに特定の状態(オープンレター/写真/ドキュメント)を保存し、このリンクを開いた別のユーザーに転送すると、あなたと同じものが表示されます。



実用的な例。




クライアントの1人が、サイトのJavascriptスライドショーフォトギャラリーを注文しました。 写真間の遷移によってページがリロードされることはありませんが、同時に特定の写真へのリンクをコピーして送信する機会を求めました。 この問題は、フラグメントアドレッシングを使用して簡単に解決できました。



写真へのリンクはsite.com/gallery/name-of-gallery/#photo_idのように見えました。ここで、photo_idは画像コードです。 カルーセルのサムネイルと同様に、進むボタンと戻るボタンは、対応する写真のコードを含むフラグメントへの通常のリンクでした。 サムネイルスライドショーコンポーネントとカルーセルは、URIフラグメントの変更イベントをインターセプトし、それに応じて反応しました(スライドショーは目的の写真を表示し、カルーセルはそれにスクロールしてフレームで強調表示しました)。 また、作成後すぐに、これらの各コンポーネントは現在のフラグメントをチェックし、写真に移行しました。



画像



アプリケーションを編成するこの原則は非常に便利です。 そのコンポーネントは、状態の変化を追跡するために互いのイベントハンドラに「固執」する必要はありません。 誰でもすぐにURIフラグメントの変更を監視し、必要なアクションを実行するだけで十分です。 多くの多対多の関係を持つシステムの代わりに、開発とデバッグがはるかに簡単な集中管理システムを取得します。



ExtJSで




ExtJSフレームワークは、フラグメントアドレッシングを操作するための便利なシングルトンExt.Historyを提供します。 それを使用する前に、する必要があります





次にサンプルコードを示します。

Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  1. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  2. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  3. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  4. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  5. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  6. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  7. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  8. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  9. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  10. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  11. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  12. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  13. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  14. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  15. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  16. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  17. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  18. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



  19. Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .



Ext.getBody().createChild({ tag: 'form' , action: '#' , cls: 'x-hidden' , id: 'history-form' , children: [{ tag: 'div' , children: [{ tag: 'input' , id: Ext.History.fieldId, type: 'hidden' }, { tag: 'iframe' , id: Ext.History.iframeId }] }] }); Ext.History.init(); * This source code was highlighted with Source Code Highlighter .







シングルトンの詳細なドキュメントは、 http://www.extjs.com/deploy/dev/docs/? class = Ext.Historyにあります 。 最も一般的に使用される機能について説明します。 Ext.Historyの用語では、フラグメントはトークンと呼ばれます。







使用例:







  1. < スクリプト タイプ =” text / javascript>
  2. Ext.onReady( function (){
  3. <ExtHistoryの初期化(上記のコードを参照)>
  4. var showToken = function (token){
  5. if (Ext.isString(token)&& token!= '' )Ext.Msg.alert( 'Token changed' 、String.format( 'New token:{0}' 、token));
  6. }、
  7. t = Ext.History.getToken();
  8. Ext.History.on( 'change' 、showToken);
  9. Ext.get( 'settoken4' ).on( 'click' 、Ext.History.add.createDelegate(Ext.History、[ 'token4' ]、 false ));
  10. showToken(t);
  11. });
  12. </ スクリプト >
  13. <a href = "# token1">トークン1 </ a > | <a href = "# token2">トークン2 </ a > | <a href = "# token3">トークン3 </ a >
  14. < 入力 タイプ = "ボタン" = "トークン4を設定" id = "settoken4" />
*このソースコードは、 ソースコードハイライターで強調表示されました。




公式デモはリンクで見ることができます



http://www.extjs.com/deploy/dev/examples/history/history.html



そして、ここで与えられたコードの仕事の例はここにあります 。 サンプルのソースコードをダウンロードすることもできます(ExtJS配布なしの代替リンク )。



MooToolsで




標準のMooTools配信にはフラグメントのアドレス指定を扱うクラスがありませんでした。プラグインが見つからなかったため、Ext.Historyシングルトンを使用することにしました。 MooToolsに適合させるのに少し時間を要しました。 また、シングルトンを少し終了しました-init()メソッドで補助フォームの作成を組み込み、jsファイルが接続されたときにシングルトンを自動的に初期化します



Mootolls-singleton IはHistoryManagerと呼ばれます。 メソッドとイベントは、Ext.Historyのメソッドとイベントと完全に同一です。



使用例:





  1. < スクリプト タイプ = "text / javascript" >
  2. window.addEvent( 'domready'function (){
  3. var showToken = function (token){
  4. if ($ type(token)== 'string' && token!= '' )alert( '新しいトークン:{t}' .substitute({t:token}));
  5. }、
  6. t = HistoryManager.getToken();
  7. HistoryManager.addEvent( 'change' 、showToken);
  8. $( 'settoken4' ).addEvent( 'click' 、HistoryManager.add.bind(HistoryManager、[ 'token4' ]));
  9. showToken(t);
  10. });
  11. </ スクリプト >
  12. </ >
  13. < 本体 >
  14. <a href = "# token1">トークン1 </ a > | <a href = "# token2">トークン2 </ a > | <a href = "# token3">トークン3 </ a >
  15. < 入力 タイプ = "ボタン" = "トークン4を設定" id = "settoken4" />
*このソースコードは、 ソースコードハイライターで強調表示されました。




ここに示されているコードの動作の例は、デモフォトギャラリー- ここにあります 。 またサンプル(ExtJS配布キットなしの代替リンク )とフォトギャラリーソースコードをダウンロードすることもできます。



PS Ext.HistoryをPrototypeまたはjQueryに翻訳する必要がある場合-お問い合わせください。



UPD: JavaScriptに移植されたカルマをありがとう



All Articles