4

AJAX を使用してページの一部を更新している間に、Lifehacker が URL を変更できることがわかりました。HTML5 または history.js プラグインを使用して実装できると思いますが、ライフハッカーはどちらも使用していないと思います。

彼らがどのようにそれを行うかについての手がかりを持っている人はいますか? 私は AJAX を初めて使用し、Ajax を使用してページの一部を更新することができました。


詳細なステップバイステップのアルゴリズムについて、@Robin Andersonに感謝します。私はそれを試してみましたが、うまく機能しています。ただし、本番環境でテストする前に、私が持っているコードを実行したいと思います。私はすべて正しく行いましたか?

<script type="text/javascript">  
var httpRequest;  
var globalurl;
    function makeRequest(url) {  
    globalurl = url;
    /* my custom script that retrieves original page without formatting (just data, no templates) */
    finalurl = '/content.php?fname=' + url ;

    if(window.XMLHttpRequest){httpRequest=new XMLHttpRequest}else if(window.ActiveXObject){try{httpRequest=new ActiveXObject("Msxml2.XMLHTTP")}catch(e){try{httpRequest=new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}}}  

    /* if no html5 support, just load the page without ajax*/
    if (!(httpRequest && window.history && window.history.pushState)) {     
            document.href = url;
            return false;  
    } 

    httpRequest.onreadystatechange = alertContents;  
    alert(finalurl);    /* to make sure, content is being retrieved from ajax */
    httpRequest.open('GET', finalurl);  
    httpRequest.send();  
    } 

    /* for support to back button and forward button in browser */
    window.onpopstate = function(event) {
            if (event.state !== null) {
                    document.getElementById("ajright").innerHTML = event.state.data;
            } else {
                    document.location.href = globalurl;
                    return false;
            };
    };    

    /* display content in div */
    function alertContents() {  
            if (httpRequest.readyState === 4) {  
            if (httpRequest.status === 200) {  
                    var stateObj = { data: httpRequest.responseText};
                    history.pushState(stateObj, "", globalurl);     
                    document.getElementById("ajright").innerHTML = httpRequest.responseText;
            } else {  
                    alert('There was a problem with the request.');  
            }  
            }  
    }  
    </script> 

PS: コメントにコードを貼り付ける方法がわからないので、ここに追加しました。

4

2 に答える 2

8

HTML5 機能であっても、ブラウザーで履歴 API を使用するためにマークアップを HTML5 にする必要はありません。

すべてのページ遷移を AJAX でロードするための非常に迅速かつ簡単な実装の 1 つを次に示します。

  1. rel="external" が存在する場所を除くすべてのリンクを関数 "ChangePage" にフックします。
  2. ChangePage がトリガーされたら、履歴 API がブラウザーでサポートされているかどうかを確認します。
  3. history API がサポートされていない場合は、ハッシュタグをプッシュするか、フォールバックとして通常の全ページ読み込みを行います。
  4. history API がサポートされている場合:
    1. 通常のリンク動作を防止します。
    2. 新しい URL をブラウザーの履歴にプッシュします。
    3. 新しい URL に AJAX リクエストを送信し、そのコンテンツを取得します。
    4. 応答で content div (または同様の要素) を探し、そこから HTML を取得し、現在のページの対応する要素の HTML を新しいものに置き換えます。

これは実装が簡単で、キャッシュの管理が簡単で、Google のロボットとうまく連携します。欠点は、「最適化」されていないことと、変更時に (より複雑なソリューションと比較して) 応答にいくらかのオーバーヘッドが生じることです。ページ。

下位互換性も備えているため、古いブラウザや「JavaScript 以外の訪問者」は、通常のページ ロードのみを取得できます。

この件に関する興味深いリンク

編集:

言及する価値のあるもう 1 つのことは、これを ASP .Net Web フォーム アプリケーションと一緒に使用しないでください。ポストバック処理が台無しになる可能性があります。

コードの追加:

この機能の小さなデモをまとめました。ここで見つけることができます

HTML、Javascript (jQuery)、およびほんの少しの CSS を使用するだけなので、使用する前にテストすることをお勧めします。しかし、Chromeでいくつかチェックしたところ、うまく機能しているようです。

私がお勧めするいくつかのテストは次のとおりです。

  • 適切なブラウザー、Chrome および Firefox でテストします。
  • IE7 などのレガシー ブラウザでテストする
  • Javascript を有効にせずにテストします (Noscript をインストールするか、Chrome/Firefox に類似したものをインストールしてください)。

これを実現するために使用した JavaScript を次に示します。完全なソースは上記のデモで確認できます。

/*
    The arguments are:          
        url: The url to pull new content from
        doPushState: If a new state should be pushed to the browser, true on links and false on normal state changes such as forward and back.
*/
function changePage(url, doPushState, defaultEvent)
{
    if (!history.pushState) { //Compatability check
        return true; //pushState isn't supported, fallback to normal page load
    }

    if (defaultEvent != null) { 
        defaultEvent.preventDefault(); //Someone passed in a default event, stop it from executing
    }

    if (doPushState) {  //If we are supposed to push the state or not
        var stateObj = { type: "custom" }; 
        history.pushState(stateObj, "Title", url); //Push the new state to the browser
    }               

    //Make a GET request to the url which was passed in
    $.get(url, function(response) {             
        var newContent = $(response).find(".content");      //Find the content section of the response
        var contentWrapper = $("#content-wrapper");         //Find the content-wrapper where we are supposed to change the content.
        var oldContent = contentWrapper.find(".content");   //Find the old content which we should replace.

        oldContent.fadeOut(300, function() { //Make a pretty fade out of the old content
            oldContent.remove(); //Remove it once it is done
            contentWrapper.append(newContent.hide()); //Add our new content, hidden
            newContent.fadeIn(300); //Fade it in!
        });

    });
}


//We hook up our events in here
$(function() {
    $(".generated").html(new Date().getTime()); //This is just to present that it's actually working.

    //Bind all links to use our changePage function except rel="external"
    $("a[rel!='external']").live("click", function (e) { 
        changePage($(this).attr("href"), true, e);
    });

    //Bind "popstate", it is the browsers back and forward
    window.onpopstate = function (e) { 
        if (e.state != null) {
            changePage(document.location, false, null); 
        }
    }
}); 
于 2011-11-20T16:48:35.197 に答える
0

DOCTYPE は、ページが使用できる機能には影響しません。

彼らはおそらく HTML5 History API を直接使用しています。

于 2011-11-20T16:25:48.670 に答える