<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>History &#8211; Mach3.laBlog</title>
	<atom:link href="https://blog.mach3.jp/tag/history/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.mach3.jp</link>
	<description></description>
	<lastBuildDate>Sun, 15 Dec 2013 01:18:38 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>
	<item>
		<title>&#034;Pjax&#034; &#8211; Alphabetical Advent Calendar 2013</title>
		<link>https://blog.mach3.jp/2013/12/15/jaac2013-p-pjax.html</link>
		
		<dc:creator><![CDATA[mach3]]></dc:creator>
		<pubDate>Sun, 15 Dec 2013 01:18:38 +0000</pubDate>
				<category><![CDATA[Laboratory]]></category>
		<category><![CDATA[Advent Calendar 2013]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[History]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Pjax]]></category>
		<category><![CDATA[pushState]]></category>
		<guid isPermaLink="false">http://blog.mach3.jp/?p=3736</guid>

					<description><![CDATA[&#8220;P&#8221; は Pjax の &#8220;P&#8221;。 Pjax Pjax とは、pushState + Ajax から作られた言葉で、 History の pushState メソッドでUR [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>&#8220;P&#8221; は Pjax の &#8220;P&#8221;。</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh3.googleusercontent.com/-rG5GncLn5AI/UqR4kF1SVpI/AAAAAAAACYg/65EXIw2yj30/s400/ac2013-p.png" alt="P"/></figure>



<p></p>



<span id="more-3736"></span>



<h2 class="wp-block-heading">Pjax</h2>



<p><strong>Pjax</strong> とは、<strong>pushState</strong> + <strong>Ajax</strong> から作られた言葉で、 History の <strong>pushState</strong> メソッドでURLを管理しつつ、 コンテンツの遷移を Ajax を使って行う手法です。</p>



<p>おおまかな流れはこのような感じ。</p>



<ol class="wp-block-list">
<li>ページ内のリンクをクリックした時にページ遷移を行わずに、 対象のHTMLファイルの内容を Ajax で取得します。</li>



<li>取得に成功したら <strong>History.pushState</strong> でURLを変更して履歴に追加します。</li>



<li>ファイルの内容から必要なコンテンツ部分を抽出して、コンテンツのコンテナに流し込みます。</li>
</ol>



<p>ページごと遷移しない為余計な部分の再描画が必要なく、 遷移時に好みのエフェクトをかけられる点などが特徴です。 また、サイト全体に共通にかかるような JavaScript などの処理をページ移動毎に行わなくて済む為、 高速化にも一役かっています。</p>



<p>その実用性についてはこちらにまとまっていましたので、ご参考までに。</p>



<ul class="wp-block-list">
<li><a href="http://d.hatena.ne.jp/fatwebstudy/20131015/1381780122">pjaxの実用性 &#8211; fatのWEB開発メモ</a></li>
</ul>



<h2 class="wp-block-heading">Pjax コンテンツを習作してみる</h2>



<p>実装の仕方は様々あると思いますが、ここで一例習作してみましょう。 （例をシンプルにする為にjQueryを使用します）</p>



<h3 class="wp-block-heading">HTML構造を共通化する</h3>


<pre class="wp-block-code"><span><code class="hljs language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"navi"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">data-pjax</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/foo.html"</span> <span class="hljs-attr">data-pjax</span>&gt;</span>Foo<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/bar.html"</span> <span class="hljs-attr">data-pjax</span>&gt;</span>Bar<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/baz.html"</span> <span class="hljs-attr">data-pjax</span>&gt;</span>Baz<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"content"</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- ここの内容を差し替えます --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, Pjax<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></span></pre>


<p>まずこのようなHTMLを想定します。 上のナビゲーション部分のリンクをクリックすると Ajax でリンク先のHTMLファイルを取得し、 <strong>#content</strong> の内容を差し替えます。</p>



<p>HTMLの構造は、遷移元・遷移先共に共通にしておきましょう。 例えば下のコードは Foo をクリックした時に表示する為の <strong>foo.html</strong> です。</p>


<pre class="wp-block-code"><span><code class="hljs language-xml"><span class="hljs-comment">&lt;!-- foo.html --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Page Foo<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
...
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"navi"</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"content"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Foo<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lorem ipsum ...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></span></pre>


<h3 class="wp-block-heading">pushState のサポートをチェックする</h3>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">if</span>(! history.pushState || ! history.replaceState){
    <span class="hljs-keyword">return</span>;
}
</code></span></pre>


<p>この例では <strong>pushState</strong> / <strong>replaceState</strong> 共に実装されていなければ正常に動かないので、 サポートしていない環境では以降の処理をスキップし、そのままネイティブの機能でページを移動してもらいます。</p>



<h3 class="wp-block-heading">リンクの制御</h3>



<p>クリックの制御は <strong>イベントのバブリング</strong> を利用して <strong>document</strong> にて行う事にします。 これならば、コンテンツ部分に新たに生成されるリンクも制御できます。 Pjax で遷移するリンクを明示する為に、ここでは <strong>data-pjax</strong> 属性を使用しています。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">$(<span class="hljs-built_in">document</span>).on(<span class="hljs-string">"click"</span>, <span class="hljs-string">"&#91;data-pjax]"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
    e.preventDefault();
    <span class="hljs-keyword">var</span> href = e.currentTarget.href;
    $.<span class="hljs-keyword">get</span>(href, function(html, status, xhr){
        <span class="hljs-comment">// コンテンツを更新する</span>
        updateContent(html);
        <span class="hljs-comment">// 履歴に追加する</span>
        history.pushState({<span class="hljs-attr">url</span>: href, <span class="hljs-attr">html</span>: html}, <span class="hljs-string">""</span>, href);
    }, <span class="hljs-string">"html"</span>);
});
</code></span></pre>


<h3 class="wp-block-heading">コンテンツの更新</h3>



<p>上のコードで使用している <strong>updateContent()</strong> 内でHTML文字列から必要な部分を抽出してコンテンツを更新します。 今回必要とするのは <strong>#content</strong> の中身と <strong>title</strong> です。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">var</span> updateContent = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">html</span>)</span>{
    <span class="hljs-keyword">var</span> title = (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
        <span class="hljs-keyword">var</span> m = html.match(<span class="hljs-regexp">/&lt;title.*?&gt;(&#91;\s\S]+?)&lt;\/title&gt;/i</span>);
        <span class="hljs-keyword">return</span> m ? m&#91;<span class="hljs-number">1</span>] : <span class="hljs-string">""</span>;
    }());
    <span class="hljs-keyword">var</span> content = (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
        <span class="hljs-keyword">var</span> m = html.match(<span class="hljs-regexp">/&lt;body.*?&gt;(&#91;\s\S]+?)&lt;\/body&gt;/i</span>);
        <span class="hljs-keyword">if</span>(m){
            <span class="hljs-keyword">var</span> content = $(<span class="hljs-string">"&lt;div&gt;"</span>).append(m&#91;<span class="hljs-number">1</span>]).find(<span class="hljs-string">"#content"</span>);
            <span class="hljs-keyword">return</span> content.length ? content.html() : <span class="hljs-string">""</span>;
        }
        <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
    }());
    <span class="hljs-built_in">document</span>.title = title;
    $(<span class="hljs-string">"#content"</span>).hide().html(content).fadeIn();
};
</code></span></pre>


<p>content のパースは厄介なので、jQueryで一時的に要素を生成してフィルタリングしています。 遷移時にはコンテンツ部分がフェードインするようにしてみました。</p>



<h3 class="wp-block-heading">popstate イベントの設定</h3>



<p>これだけではリンクをクリックした時だけしかコンテンツが変わらないので、 ブラウザの進む・戻るボタン等で履歴を移動した場合にもコンテンツが切り替わるように、 <strong>popstate</strong> イベントの設定をします。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">$(<span class="hljs-built_in">window</span>).on(<span class="hljs-string">"popstate"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
    <span class="hljs-keyword">var</span> state = e.originalEvent.state;
    <span class="hljs-keyword">if</span>(state &amp;&amp; state.html){
        updateContent(state.html);
    }
});
</code></span></pre>


<p>jQuery.fn.on でイベント設定した場合は e.state ではなく e.originalEvent.state と辿らなければいけないので注意が必要です。 pushState で登録しておいた <strong>html</strong> が state から取得出来るので、それを使用してコンテンツをその時の状態に戻します。</p>



<h3 class="wp-block-heading">現在いるページで初期化をする</h3>



<p>一番最初に訪れたページの内容で、state の初期化を行います。 そうしなければ、ページ遷移を行ったあとに一番はじめのページまで履歴をさかのぼった時に state が空っぽな為、コンテンツを更新してくれません。</p>


<pre class="wp-block-code"><span><code class="hljs language-css"><span class="hljs-selector-tag">history</span><span class="hljs-selector-class">.replaceState</span>({<span class="hljs-attribute">url</span>: location.href, html: $(<span class="hljs-string">"html"</span>).<span class="hljs-built_in">html</span>()}, "", <span class="hljs-selector-tag">location</span><span class="hljs-selector-class">.href</span>);
</code></span></pre>


<h3 class="wp-block-heading">ファイナルコード</h3>



<p>シンプルな構成ですが、こんな感じになりました。 実際にはエラー時の処理や、コンテンツのキャッシュ等も入るかもしれません。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{

    <span class="hljs-keyword">if</span>(! history.pushState || ! history.replaceState){
        <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">var</span> updateContent = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">html</span>)</span>{
        <span class="hljs-keyword">var</span> title = (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
            <span class="hljs-keyword">var</span> m = html.match(<span class="hljs-regexp">/&lt;title.*?&gt;(&#91;\s\S]+?)&lt;\/title&gt;/i</span>);
            <span class="hljs-keyword">return</span> m ? m&#91;<span class="hljs-number">1</span>] : <span class="hljs-string">""</span>;
        }());
        <span class="hljs-keyword">var</span> content = (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
            <span class="hljs-keyword">var</span> m = html.match(<span class="hljs-regexp">/&lt;body.*?&gt;(&#91;\s\S]+?)&lt;\/body&gt;/i</span>);
            <span class="hljs-keyword">if</span>(m){
                <span class="hljs-keyword">var</span> content = $(<span class="hljs-string">"&lt;div&gt;"</span>).append(m&#91;<span class="hljs-number">1</span>]).find(<span class="hljs-string">"#content"</span>);
                <span class="hljs-keyword">return</span> content.length ? content.html() : <span class="hljs-string">""</span>;
            }
            <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
        }());
        <span class="hljs-built_in">document</span>.title = title;
        $(<span class="hljs-string">"#content"</span>).hide().html(content).fadeIn();
    };

    $(<span class="hljs-built_in">document</span>).on(<span class="hljs-string">"click"</span>, <span class="hljs-string">"&#91;data-pjax]"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
        e.preventDefault();
        <span class="hljs-keyword">var</span> href = e.currentTarget.href;
        $.<span class="hljs-keyword">get</span>(href, function(html, status, xhr){
            updateContent(html);
            history.pushState({<span class="hljs-attr">url</span>: href, <span class="hljs-attr">html</span>: html}, <span class="hljs-string">""</span>, href);
        }, <span class="hljs-string">"html"</span>);
    });

    $(<span class="hljs-built_in">window</span>).on(<span class="hljs-string">"popstate"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
        <span class="hljs-keyword">var</span> state = e.originalEvent.state;
        <span class="hljs-keyword">if</span>(state &amp;&amp; state.html){
            updateContent(state.html);
        }
    });

    history.replaceState({<span class="hljs-attr">url</span>: location.href, <span class="hljs-attr">html</span>: $(<span class="hljs-string">"html"</span>).html()}, <span class="hljs-string">""</span>, location.href);

}());
</code></span></pre>


<h2 class="wp-block-heading">ライブラリを利用する</h2>



<p>上の説明用のコードは単機能で汎用性にも欠け、いささか面倒です。 既に Pjax のライブラリは多くの方が公開していると思いますので、 それを利用させてもらいましょう。</p>



<h3 class="wp-block-heading">jquery-pjax</h3>



<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
https://github.com/defunkt/jquery-pjax
</div></figure>



<p>jquery-pjax は名前の通り Pjax の面倒な処理ひと通りこなしてくれるjQueryプラグインです。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">$(<span class="hljs-built_in">document</span>).pjax(<span class="hljs-string">"a&#91;data-pjax]"</span>, <span class="hljs-string">"#container"</span>);
</code></span></pre>


<p>jquery-pjax は Ajaxのリクエストに <strong>X-PJAX</strong> というヘッダを追加してくれます。 サーバサイドでそのヘッダを検知して、共通レイアウトを省いたコンテンツ部分のみを出力するようにすれば、 データ量の節約になるという寸法です。</p>



<p>レイアウトを省かないHTMLを読み込んで部分だけ使用したい場合（上であげたコードのようなケース）は、 <strong>fragment</strong> オプションでセレクタを指定する必要がありますので注意しましょう。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">$(<span class="hljs-built_in">document</span>).pjax(<span class="hljs-string">"a&#91;data-pjax]"</span>, <span class="hljs-string">"#container"</span>, {
    <span class="hljs-attr">fragment</span>: <span class="hljs-string">"#container"</span>
});
</code></span></pre>


<h2 class="wp-block-heading">参考資料</h2>



<ul class="wp-block-list">
<li><a href="http://d.hatena.ne.jp/fatwebstudy/20131015/1381780122">pjaxの実用性 &#8211; fatのWEB開発メモ</a></li>



<li><a href="https://developer.mozilla.org/ja/docs/Web/Guide/DOM/Manipulating_the_browser_history">Manipulating the browser history &#8211; Web developer guide | MDN</a></li>



<li><a href="https://github.com/defunkt/jquery-pjax">defunkt/jquery-pjax</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>&#034;History&#034; &#8211; Alphabetical Advent Calendar 2013</title>
		<link>https://blog.mach3.jp/2013/12/07/jaac2013-h-history.html</link>
		
		<dc:creator><![CDATA[mach3]]></dc:creator>
		<pubDate>Sat, 07 Dec 2013 00:10:32 +0000</pubDate>
				<category><![CDATA[Laboratory]]></category>
		<category><![CDATA[Advent Calendar 2013]]></category>
		<category><![CDATA[History]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[pushState]]></category>
		<guid isPermaLink="false">http://blog.mach3.jp/?p=3670</guid>

					<description><![CDATA[&#8220;H&#8221; は History の &#8220;H&#8221;。 History による履歴操作 一画面で構成される様なWebアプリケーションで ユーザーに「戻る」ボタンなどの履歴移動機能を提供し [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>&#8220;H&#8221; は History の &#8220;H&#8221;。</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh3.googleusercontent.com/-pWrjGJsaVbU/UqR4hHiOSnI/AAAAAAAACYg/1c--4PFVcFo/s400/ac2013-h.png" alt="H"/></figure>



<p></p>



<span id="more-3670"></span>



<h2 class="wp-block-heading">History による履歴操作</h2>



<p>一画面で構成される様なWebアプリケーションで ユーザーに「戻る」ボタンなどの履歴移動機能を提供したい場合、 旧来は <strong>location.hash</strong> を使用していました。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">"hashchange"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-comment">/* location.hash が変更された時の処理 */</span>
}, <span class="hljs-literal">false</span>);
location.hash = <span class="hljs-string">"foo"</span>; <span class="hljs-comment">// "#foo" に移動</span>
</code></span></pre>


<p>URL末尾のハッシュは更新されますが 表示されているドキュメント自体は切り替わらず、 そのハッシュの名前によってページの一部を切り替えたり、 少し変わったトランジションをかけてページを移動したりする事が出来ます。 URLの文字は変更されているので、その状態をブックマークする事も出来ます。</p>



<p>最近ではその役割に、Historyオブジェクトに新たに実装された <strong>pushState</strong> が取って代わりつつあります。</p>



<h2 class="wp-block-heading">History.pushState を使う</h2>



<p>まず、History オブジェクト自体は一度は使った事がある代物だと思いますが、 window にぶらさがっているあの history の事です。 配列のように履歴の情報をスタックしていけるようなオブジェクトで、 go/back/forward() メソッドを使うことでその履歴間を行き来する事が出来ます。</p>



<p>pushState() は、Historyオブジェクトに新しく履歴のエントリを追加し、そこに移動するメソッドです。 例えば <strong>http://example.com</strong> のページで次のような処理をした場合。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">var</span> url = <span class="hljs-string">"/foo"</span>;
history.pushState({<span class="hljs-attr">url</span>: url}, <span class="hljs-string">""</span>, url);
</code></span></pre>


<p>アドレスバーのURLは <strong>http://example.com/foo</strong> に切り替わりますが、ページの表示はそのままです。 pushState をコールした後に自分で好きなようにドキュメントを弄ってください。</p>



<p>pushStateの引数は1つ目から順に <strong>stateオブジェクト</strong>、<strong>タイトル</strong>、<strong>URL</strong> となっています。</p>



<ul class="wp-block-list">
<li><strong>stateオブジェクト</strong> : 履歴のエントリと状態を結びつけるためのデータ。<br /><br />その履歴に戻った時にページの状態を戻すための情報を格納しておきます。</li>



<li><strong>タイトル</strong> : MDN曰く、現在は無視されているパラメータ。将来的に使う事になるでしょう。</li>



<li><strong>URL</strong> : アドレスバーの表示を切り替える為のURL。</li>
</ul>



<p>ちなみに <strong>replaceState</strong> というメソッドも実装されていて、同様の引数で利用できます。 こちらは履歴のスタックに push するのではなく、現在いるエントリを上書きするメソッドです。</p>



<h3 class="wp-block-heading">ターゲットURL と ページ</h3>



<p>指定したURLに実際にページが存在しない場合、 ページをブラウザでリフレッシュしたり改めてアクセスしたりすると Not found になってしまいますので、 実際にファイルを設置するか、mod_rewrite や サーバサイドのスクリプトでどうにかする必要があります。</p>



<p>あるいは、URLに &#8220;#foo&#8221; などを指定する事も出来ます。 これならば同じページで展開する事が出来ます…が、pushState である必要性が少し薄くなる気もします。</p>


<pre class="wp-block-code"><span><code class="hljs language-css"><span class="hljs-selector-tag">history</span><span class="hljs-selector-class">.pushState</span>({<span class="hljs-attribute">hash</span>: <span class="hljs-string">"#foo"</span>}, "", "<span class="hljs-selector-id">#foo</span>");
</code></span></pre>


<h2 class="wp-block-heading">popstate イベント</h2>



<p>location.hash における <strong>hashchange</strong> イベントと似た役割を持つのが <strong>popstate</strong> イベントです。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">"popstate"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
    e.state; <span class="hljs-comment">// {url: "/foo"} など</span>
}, <span class="hljs-literal">false</span>);
</code></span></pre>


<p>イベントハンドラに渡される Event オブジェクトには <strong>state</strong> オブジェクトがぶら下がっていますが、 これは pushState で設定した state オブジェクトです。 ここから情報を参照して、ページの状態を復元する事になります。</p>



<p>注意しなければならないのはイベント発火のタイミングです。 hashchange イベントは location.hash を変更した時点で発火しましたが、 popstate イベントは pushState をコールした時点では発火せず、 次の方法で「履歴を移動した時点」で発火します。</p>



<ul class="wp-block-list">
<li>ページロード時</li>



<li>ブラウザの「戻る」「次へ」ボタンや、そのショートカットキーで移動</li>



<li>history.go/back/forward() で移動</li>
</ul>



<p>要するに、popstate イベントは pushState 以外の操作で履歴を移動した場合にページをその履歴の時点の状態に戻す為に使用するイベントだ、という事です。</p>



<p>これらの機能を使いつつ Ajax と連携してコンテンツを遷移する <strong>&#8220;pjax&#8221;</strong> という手法もありますが、それはまた別のお話。</p>



<h2 class="wp-block-heading">参考資料</h2>



<ul class="wp-block-list">
<li><a href="https://developer.mozilla.org/ja/docs/Web/Guide/DOM/Manipulating_the_browser_history">Manipulating the browser history &#8211; Web developer guide | MDN</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
