TopMovable Typeカスタマイズ検索 > 2008年6月
2008年6月20日

Movable Type 4.2 の Ajax 検索機能

June 20,2008 12:55 PM
Tag:[, , ]
Permalink

Movable Type 4.2 の検索機能ではページ分割が導入されました。

検索結果のページ分割

検索結果が複数のページに跨る場合(=ページ分割された場合)は、Google マップのスクロールのように、次の検索結果ページを Ajax で事前に取得します。
その結果、分割ページに移動するときは、ストレスのないページ送りができるようになっています。瞬時に前後ページに移動できるので、かなり快適です。
ただし、初回の検索は Ajax ではありません。

本エントリーでは、検索結果ページで使われている JavaScript をかなり簡単に紹介します。

1.getResults

MTIfMoreResultsタグで、検索結果がページ分割されている場合にこのコードがページに展開され、現在の検索結果の表示中にバックグラウンドで Ajax を起動し、次のページの検索結果を取得・保持します。

<MTIgnore>Below Javascript adds ajax search capability</MTIgnore>
<script type="text/javascript">
/* <![CDATA[ */
<MTIfMoreResults>
function getResults(page) {
    page = parseInt(page);
    if (timer) window.clearTimeout(timer);
    var xh = mtGetXmlHttp();
    if (!xh) return false;
    var res = results[page];
    if (!res) return;
    var url = res['next_url'];
    if (!url) return;
 
    xh.open('GET', url + '&format=js', true);
    xh.onreadystatechange = function() {
        if ( xh.readyState == 4 ) {
            if ( xh.status && ( xh.status != 200 ) ) {
                // error - ignore
            } else {
                try {
                    var page_results = eval("(" + xh.responseText + ")");
                    if ( page_results['error'] == null )
                        results[page + 1] = page_results['result'];
                } catch (e) {
                }
            }
        }
    };
    xh.send(null);
}
...中略...
</MTIfMoreResults>
/* ]]> */
</script>

この関数は、検索結果ページに埋め込まれた次のスクリプトで実行されます。

<MTIgnore><!-- Used with the ajax search capability of the new search class --></MTIgnore>
<MTIfMoreResults>
<script type="text/javascript">
<!--
var div = document.getElementById('search-results');
var results = {
    '<MTCurrentPage>': {
        'content': div.innerHTML,
        'next_url': '<MTNextLink>'
    }
};
var timer = window.setTimeout("getResults(" + <MTCurrentPage> + ")", 1*1000);
//-->
</script>
</MTIfMoreResults>

次のページのURLは、getResults の内部処理で JSON 型の変数 results の next_url にアクセスし、MTNextLinkタグで展開された URL を取得します。

getResults は、周期処理を行うための window.setTimeout で起動され、getResults の内部処理の window.clearTimeout で周期処理を停止します。つまり1回しか起動されません。また、1秒周期で実行するため、検索結果が表示されてからすぐにリンクをクリックすると、Ajax による次のページ取得が完了していない場合があります。

2.swapContent

検索結果本文を、保持している前後の検索結果と置き換えます。

<script type="text/javascript">
/* <![CDATA[ */
<MTIfMoreResults>
...中略...
function swapContent(direction) {
    if ( direction == undefined ) direction = 1;
    var page_span = document.getElementById('current-page');
    if (!page_span) return true;
    var next_page = direction + parseInt(page_span.innerHTML);
    var res = results[next_page];
    if (!res) return true;
    var content = res['content'];
    if (!content) return true;
    var div = document.getElementById('search-results');
    if (!div) return true;
    div.innerHTML = content;
    timer = window.setTimeout("getResults(" + next_page + ")", 1*1000);
    window.scroll(0, 0);
    return false;
}
<MTElse><MTIfPreviousResults>
function swapContent(direction) {
    return true;
}</MTIfPreviousResults>
</MTIfMoreResults>
/* ]]> */
</script>

この関数は、検索結果ページに埋め込まれたページ移動用のナビゲーションの「前」「次」のリンクから実行されます。

<MTIgnore><!-- Used with the ajax search capability of the new search class --></MTIgnore>
<div class="content-nav">
<MTIfPreviousResults>
  <a href="<MTPreviousLink>" rel="prev" onclick="return swapContent(-1);">&lt; 前</a>&nbsp;&nbsp;
</MTIfPreviousResults>
<MTPagerBlock>
  <MTIfCurrentPage>
    <MTVar name="__value__">
  <MTElse>
    <a href="<MTPagerLink>"><MTVar name="__value__"></a>
  </MTIfCurrentPage>
  <mt:unless name="__last__">&nbsp;</mt:unless>
</MTPagerBlock>
<MTIfMoreResults>&nbsp;&nbsp;<a href="<MTNextLink>" rel="next" onclick="return swapContent();">次 &gt;</a>
</MTIfMoreResults>

なお、Ajax によるページ移動は「前」「次」のリンクを使った場合のみ有効で、ページ番号のリンクをクリックしたときは通常のCGI起動になります。

3.注意事項

ページ分割時の Ajax を有効に活用するには、次の青色の1行が必要です。

...前略...
<MTSearchResults>
  <MTSearchResultsHeader>
    <div id="search-results">
      <span id="current-page" class="hidden"><MTCurrentPage></span>
      <h1 id="page-title" class="search-results-header">
...後略...

関数 swapContent の内部処理で、現在のページ番号をここから取得しています。

Comments [4] | Trackbacks [0]
Now loading...
ギターに入った猫
掲載広告募集
Styles
Font Size
Default
For defective color vision
Gray Scale
RGB Color
Search this site

このブログをメールで購読する by:FeedBurner

AMN
Categories
Monthly Archives
2020年
2019年
2018年
2017年
2016年
2015年
2014年
2013年
2012年
2011年
2010年
2009年
2008年
2007年
2006年
2005年
2004年
2003年
BlogPeople
Syndicate this site
FeedBurner(RSS1.0/RSS2.0/Atom)
Counter
これまでのアクセス
Powered by
Movable Type 6.0.3