HistoryAPI:頭を痛めないように一度書く方法

良い一日!



比較的最近のhtml5 HistoryAPIはすでに非常に人気があります。 インターネットでは、HistoryAPIの作業を増やす方法に関する多くの記事を見つけることができますが、同時にそれらはほとんど単調であり、2つのニュアンスがあります。



  1. すべてのリンクを同じ方法で処理するように編成されています。
  2. 自分で足を撃つことができますが、その理由はわかりません。


この記事では、HistoryAPIの作業を整理して、悪魔に魂を売らないようにし、すべてが機能するようにする方法について説明します。



だから、ほとんどの記事は何を提供していますか:



いくつかのナビゲーションリンクとコンテンツブロック-最もスタートアップレイアウトオプションがあるとします。



<!DOCTYPE html> <html> <head> <...> </head> <body> <nav> <a href="//<?=$_SERVER['HTTP_HOST']?>"></a> <a href="/about"> </a> <a href="/contact"> </a> </nav> <div id="content"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus, odio. </div> </body> </html>
      
      





そして、同じ平均最小値js:



 $(document).ready(function(){ $('a').click(function(e){ e.preventDefault(); var url = $(this).attr('href'); $.ajax({ url: url, data: 'ajax=true', success: function(data){ //  ,           $('#content').html(data.content); } }); window.history.pushState(null, null, url); return false; }); $(window).bind('popstate', function(){ $.ajax({ url: history.location, data: 'ajax=true', success: function(data){ $('#content').html(data.content); } }); }); });
      
      





ここで何が悪いのですか:



  1. このjsはすべてのリンクを同じ方法で処理します。外部、ローカル、さらにどこにもリダイレクトしないリンク(たとえば、モーダルウィンドウを開くリンクを作成した場合)です。 そして、庭で、一瞬、2017年。 さまざまなサイトのどこにも通じないリンクがたくさんあります。 外部リンクは通常、新しいタブで開くことができます(良いトーン)。
  2. 変数ブロックにローカルリンクがあるとすぐに、あなたは運命にあります。 スクリプトによって処理されず、その理由さえ理解できないためです。


どうする?



問題1は非常に簡単に解決できます。href属性を持つリンクのみをキャッチする必要があります(たとえば、モーダルウィンドウへのリンクの場合、<a modal_url="/url" modal_header= preferredHeader> title = choiceTitle >>のような構造を使用します)ローカルリンクかどうかを理解します。 これに応じて、異なる方法で処理します。



サイトの1つでHistoryAPIを上げることに従事していたときに問題2に遭遇しました。 ところで、これはオンラインラジオなので、ページを更新せずにサイト内を移動することは、基本的に重要なタスクです。 何が問題でしたか:ページを更新した後のリンクの最初のクリックはうまくいきました。 しかし、その後、ある種の悪魔化が始まりました。一部のリンクは正常に機能し続けましたが、他のリンクはページのリロードにつながりました。 解決策を検索してから2か月後にようやく、最初はページになかったが、ページが読み込まれた後にリンクが終了したリンクのみがサタン化されていることがわかりました。 そして、彼らはサタンです。なぜなら、彼らは盗聴イベントのクリックを切断しないからです。



 //,  : $(document).ready(function(){ $('a[href]').click(function(e){
      
      





このコードの仕組み:



1.ログインしています

2.スクリプトはページがロードされるのを待っています。

3.それをスキャンし、クリックイベントハンドラーのhref属性を持つすべてのリンクでハングします。

4.すべて。 これで彼の仕事は終わり、彼は死ぬ。



突然ね ただし、すべてのリンクを常に処理する必要があります。



最初のアイデアは、ページ更新機能で再スキャンをハングアップすることです-しかし、これは何も、追加のコードにつながりません。



2番目のアイデアは、onclick = "foo(this)"のアイデアに戻ることですが、これを行うべきではないと既に決めています。



Googleとの簡単なデート。 解決策があります



 $(document).ready(function(){ $(document).on('click', 'a[href]', function(e){
      
      





このコードの動作は少し異なります。ここでは、スクリプトがドキュメントを検索しています...ドキュメントを探しています。 そして、それはすべてのクリックをキャッチし、href属性を持つリンクのクリックにのみ反応します。 それは奇妙で、最初のオプションと不可解に似ていますが、動作します。



最終バージョン:



このソリューションにより、リンクハンドラを1回作成し、新しい投稿を作成するときにリンクに属性を追加する必要性を忘れることができます。 また、サイトに新しいエントリを作成できるすべての人に、リンクを正しく挿入する方法を説明する必要性から。



 $(document).ready(function(){ var pattern = new RegExp("^(https:\/\/"+location.host+"\/|http:\/\/"+location.host+"\/|\/\/"+location.host+"\/|"+location.host+"\/|\/(?!\/))"), // "^\/(?!\/)" - "  /,   -  /" pattern_protocol = new RegExp("^(http:\/\/|https:\/\/|\/\/)"), // , "  "   pattern_lochost = new RegExp("^("+location.host+")"); $(document).on('click', 'a[href]', function(e){ e.preventDefault(); if(!$(this).attr('href')){console.log('no href'); return false;} var url = $(this).attr('href'), isLocal = (pattern.test(url)) ? true : false; if(isLocal){ console.log('Local link: '+url); if(pattern_protocol.test(url)){url = url.replace(pattern_protocol, '');} if(pattern_lochost.test(url)){url = url.replace(pattern_lochost, '');} //     ,    . .., , "https://domain.com/page" -> "/page". //  ,       domain.com/page,     isLocal, //     - domain.com/domain.com/page $.ajax({ //    :      //string data.title //string data.url // bool data.isErrorPage // bool data.hideSidebar //     ,    $('selector').load(data.url+' selector')    . //    -  . url: url, data: 'ajax=true', success: function(data){ reload_page($.parseJSON(data)); } }); window.history.pushState(null, null, url); return false; }else{ console.log('External link: '+url); //       ,    ,     ,   location.href/url (, domain.com/google.com) // http://.    ,   https:// -  . url = (pattern_protocol.test(url)) ? url : 'http://'+url; window.open(url, '_blank'); } }); $(window).bind('popstate', function(){ $.ajax({ url: location.pathname+location.search, data: 'ajax=true', success: function(data){reload_page(data)} }); }); });
      
      





ftp://またはssh://などへのリンクを取得できる場合 -これらのリンクの処理に注意する必要があります。 気にしませんでした 彼らは私に出くわすことはありません。



それだけです お役に立てば幸いです。



All Articles