Grails、jQuery、AJAX:アンカーナビゲーションを行います。 パート1

AJAXおよびすべて、すべて、すべて



前のシリーズでは、jQueryを使用して簡単なGrailsアプリケーションを作成し、GrailsでjQueryを使用することは可能であり、必要であると判断しました。 そのような束でできるもっと深刻なことを議論します。



ますます多くのサイトがAJAXおよび部分的なページ更新を使用していることは、驚くほどの量です。 特に、「詰められた」AJAXリンクはページ上の内部ナビゲーションに使用でき、いくつかのタブを切り替えます。 これはいいから

A)サーバーから抽出する必要があるデータが少なくなります-ページの必要な部分のみと

B) Webページは単純に巨大なCSSおよびJavaScriptファイルをロードすることが多く、これらはAJAX更新中にリロードできません。



そのため、スクリプトアプリケーションの構築は非常に一般的です。1つの大きな「スタート」ページですべてのJavaScriptコードとCSSをロードし、小さな「内部」ファンクションブロックをAJAXでロードします。 これには多くの問題があります。

  1. AJAXアクションの結果として、ページの内部状態はブラウザーのアドレスバーに反映されません。
  2. 結果として、内部ページはブックマークできず、「友人へのリンクを送信」できません。
  3. ブラウザの戻る/進むナビゲーションは機能しません。 AJAXリンクはブラウザの履歴には含まれません。
ただし、大規模なサイトでは、何らかの「ハッカー」ソリューションが見つかっているため、GrailsとjQueryで独自の類似物を少し検討して記述します。



アンカーナビゲーション



実際には、アンカーのみを変更すると、ページをリロードせずにブラウザのアドレスバーを変更できる、ということです。 バーに続くアドレスバーの最後の部分は#



です。 ブラウザーはページ内でこの遷移を認識し、ページ上の目的のアンカーが存在しない状況を静かに無視し、アドレスと履歴を更新するだけです。 これがまさに必要なものです。 ページの状態をアンカー内に保存すると、ブックマークを介してページに戻ることができ、戻る/進むトランジション(!)を使用できます。 この場合、ページのベースURLは変更されず、ページはリロードされません。



そのようなソリューションの実装の例に目を向ける必要はありません。 このスキームは、Facebook、Gmail、Google Picasaウェブアルバムで使用されています。このかなりの部分はodnoklassniki.ruで見ることができます。 Google Web Toolkitライブラリは、アンカーナビゲーションに完全に基づいています。



Gmailでは、レターへの直接リンクを取得でき、リンクはブックマーク可能になります。 リンクは次のようになります。



mail.google.com/mail/?shva=1 #inbox/12c5f14c01a5473c







12c5f14c01a5473c



が手紙の内部IDのようなものであるという12c5f14c01a5473c



はありません。



アプリケーションを書く



このアプローチの実装について考えてみましょう。 アドレスバーの変更は次のとおりです。



 document.location.hash = '#myAnchor';
      
      





(または直接リンクから
 <a href="#myAnchor">My Link</a>
      
      







興味をそそるmy-appという名前のGrailsアプリケーションの作成を始めましょう。ナビゲーションは完全にAJAXに基づいています。 アプリケーションには3つのタブがあります。



アンカー1



外見は通常のページのように見えますが、完全なリロードなしでページの内部のみが更新されるようにする必要があります。



最初に、次の形式のSiteMeshレイアウトを描画します。



grails-app/views/layouts/main.gsp





 <html> <head> <title><g:layoutTitle default="Grails" /></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" href="${resource(dir:'css',file:'main.css')}" /> <g:layoutHead /> <g:javascript library="jquery"/> <g:javascript library="application" /> </head> <body> ... %{--   --}% <div class="navbar"> <div class="navitem"> <a href="#do/receipts" class="navlink"></a> <div class="spinner" /> </div> <div class="navitem"> <a href="#do/buy" class="navlink"> </a> <div class="spinner" /> </div> <div class="navitem"> <a href="#do/feedback" class="navlink"></a> <div class="spinner" /> </div> </div> %{--   --}% <div id="pageContent"> <g:layoutBody /> </div> ... </body> </html>
      
      







ここにはまだ驚きはありません。 ご覧のとおり、リンクは通常のアンカーリンクと変わりません。 彼らはどのように機能しますか? これを行うには、jQueryでそのようなコードを記述します。



web-app/js/application.js





 //      var currentState = ''; function buildURL(anchor) { return document.location.toString().substr(0, document.location.toString().indexOf('#')) + anchor.substr(1); } function clickNavLink() { //  ? var href = $(this).attr('href'); //       if (href == currentState) { return false; } if (document.location.hash != href) { document.location.hash = href; } //   var link = this; //    $(this).parent().find('.busy').show(); $(this).hide(); var targetURL = buildURL(href); currentState = href; //   ,     $.ajax({ context:$('#pageContent'), url:targetURL, dataType:'html', method:'GET', complete: function() { //   . $(link).show(); updateNavLinks(); }, success: function(data) { //  ""  . $('#pageContent').html(data); } }); return true; } //   ,   / function updateNavLinks() { $('a.navlink').each(function(i) { var href = $(this).attr('href'); $(this).parent().find('.busy').hide(); if (href == currentState) { $(this).addClass('disabled'); } else { $(this).removeClass('disabled'); } }); } // .     . jQuery(document).ready(function() { $('a.navlink').each(function() { $(this).click(clickNavLink); }); });
      
      







ここのすべては非常に簡単です。ページの現在の状態をJavaScript変数currentStateに保存します。 リンクをクリックすると、AJAX経由で内部ページが読み込まれ、AJAX呼び出しの結果がdiv#pageContentに保存されます。 この場合、読み込まれたページのURLは、ページのベースアドレスにアンカーパスを追加することで形成されます。



 /my-app/#do/receipts => /my-app/do/receipts
      
      





この単純なルールは、リンクが何をするかをすぐに理解するのに役立ちます。 リンクを「現在」として認識するために、 disabled



クラスをそれに割り当てます。 CSS(これは提供しません)では、このクラスが異なる色で表示されるため、どのリンクが現在(訪問済み)であるかがわかります。



サーバー側



サーバースタッフィングを作成するといいでしょう。 3つのリンクすべてを処理する単純なコントローラーを作成しました。



grails-app/controllers/DoSomethingController.groovy





 class DoSomethingController { def receipts = { [receipts:['  ', '']] } def buy = { [places:['  ', ' №1']] } def feedback = { [feedback:['',' ',' ,  !']] } }
      
      







そして彼のために3つの簡単なページを作りました そのうちの1つだけを提供します。



grails-app/views/doSomething/receipts.gsp





 <%--   --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <meta name="layout" content="main" /> </head> <body> <h1>    </h1> <ul> <g:each in="${receipts}" var="receipt"> <li>${receipt.encodeAsHTML()}</li> </g:each> </ul> </body> </html>
      
      







ここで/ do / *リンクにコントローラーを掛けます:



grails-app/conf/UrlMappings.groovy





 class UrlMappings { static mappings = { "/do/$action?/$id?" { controller = 'doSomething' } } }
      
      







ただし、これでは十分ではありません。 問題があります。クライアントとサーバーの部分を完成させる必要があります。これについては次の部分で説明します。



All Articles