部分的なリロードを実現する「Ajax」

ネットのページは、最初は「URL」を指定してページを開きます。 それが初めて開いたページなら、そのアドレスからページを構成する様々なデータを取得して、ページ全体が出来上がる様子を、ほんの僅かの時間ですが見守る形になります。

 

一方ブログページの場合は、ちょっと違います。 ページのかなりのデータは既にPC側にダウンロードされていて、ユーザーのページャー操作で記事本文の部分等が差し換えられて、ページが完成します。

 

この「ページ上の一部を差し換える」技術は、「ajax通信」という機能で実現しているそうで、現代のウェブ技術を支える重要な機能です。 これがないと、ユーザー操作に即応するデザインが作れず、少しの操作ごとにページがリロードする扱い難いページになります。

 

この間、ブログの「テーマ変更」のツールを作って来ましたが、記事リストがテーマ変更で変化します。 操作によって1件の移動になったり、20件全部の記事が他のリストに移動したりと、変化は色々です。 変更の結果は、ページをリロードする事で初めて判るのですが、リロードでスクロール位置が変化する事が多く、ユーザーは変更前後の推移が判り難くなります。

 

この操作性の改善に、「ajax」による「ページの部分的な更新」の機能が必要になりました。 そこでネットの情報を調べたのですが、「ajax」でデータを取得してから「ページの一部を差し換える」ところまで踏み込んだ説明が見つかりません。 結局、手探りでそれを実現したのですが、以下に具体的なサンプルを示します。

 

 

Ajax の基本的なコード 

データを「ajax通信」で取得するコードについては、沢山の情報があります。 そこから教わって少し書き直しましたが、特別な事はありません。 ただし、正確を期すなら、通信エラーなどに対応するFixコードがあれば万全です。 しかし、現在のブログページ上の一部データの更新では、必要を感じなかったので省略しています。

 

let part=document.querySelector('#part_block');
let url=location.href; // 現在のページのURL
ajaxUpdate(url, part); // ページの部分的な更新を実行

function ajaxUpdate(url, elem){ // XMLHttpRequestを使ってAjaxで更新
    url=url+'?ver='+new Date().getTime(); // キャッシュを抑止して取得
    let ajax=new XMLHttpRequest;
    ajax.open('GET', url, true);

    ajax.onload=function(){ // データ取得時の操作
        let tmp=document.createElement('div');
        tmp.setAttribute('id', 'tmp_div');
        tmp.style.display='none';
        let tmp_div=document.querySelector('#tmp_div');
        if(!tmp_div){
            document.querySelector('body').appendChild(tmp); }

        tmp.innerHTML=ajax.responseText; // 取得データをtmpに展開
        elem.innerHTML=tmp.querySelector('#part_block').innerHTML;
        tmp.innerHTML=''; } // 取得データを削除

    ajax.send(null); } // ajax開始

 

 

説明 

コードの目的は、ページ上の「#part_block」という div要素を「ajax」で差し換えて更新するためのコードです。

 

最初の3行は実行指定です。 差し換える要素の指定と、その要素があるページを指定して、3行目の「ajaxUpdate(url, part)」という関数を実行しています。 この関数が主要な関数で、後の部分は全てその関数の内容です。

 

関数の最初の4行と、最後の1行は、XMLHttpRequestの説明でよく登場する雛形的なコードです。 この説明は、ネット上の説明に譲ります。

 

上記のコードの肝心な部分は、太字の「データ取得時の操作」です。 この部分の説明を書いたページが見つかりませんでした。 おそらく、実装時はこの様なコードが必要な場合が多く、もっとスマートなコードや方法があるかも知れません。

 

 データ取得時の操作

太字部の最初の6行で「#tmp_div」という「div」要素を生成しています。 これは、ajax通信で取得されるページ全体のHTMLデータ(textで取得されます)を、実体的な要素にするための器です。

 

自分でサイトを作り、そのサイトのページ上で差し換え表示をするなら、ajaxに渡す差し換え用のデータを用意できます。 実際に多くのページでajaxはその様に使われているでしょう。

 

しかし、ユーザースクリプトで動作するツールでは、ajaxでページ上の一部の要素だけの差し換えデータを取得する事は、普通は不可能です。 取得はページ全体という事になり、これでは通常のページのリロードと同じです。

 

そこで、ページ全体のデータを取得できたら、差し換えに必要な部分のみを抜き出す必要があります。 上記のコードで、太字の最後の3行でそれをしています。

 

「 tmp.innerHTML=ajax.responseText; // 取得データをtmpに展開」

ここで「tmp」は、先の「#tmp_div」の事です。 このコードで取得した更新されたページが、スクリプトを動作させているページの下側にもう1個割込む事になります。 更新されたページは「tmp」の中で実体化しますが、どんな表示崩れを生じるか判らないので、あらかじめ「tmp」には「display: none」を指定しています。

 

次の行で、実体化した更新ページから、差し換えに必要な「#part_block」の部分だけを取得し、その中身を「elem」の中身に注入しています。

 

太字の最後行は「tmp」の中で実体化した「更新ページ」を削除しています。 これは特に必要はないですが、落ち着かないのでリセットしました。

 

 

実装コードの効果 

「ajax」を使ったコードは、ページ上の一部の要素を「innerHTML」で差し換えるので、スクロールが生じません。 これは正に目的とした結果でした。

 

ただし、リロードすれば新しく表示される要素に対してスクリプトが動作しますが、「ajax」で差し換えられた要素は「再取得」しないとスクリプトが動作しません。 つまり「再取得」を上手く設定できないと、「ajax」を使った意味がなくなります。

 

これまでのツール制作では、ページング操作でスクリプトが動作しなくなって、何度も苦労しました。 実用的なツールを制作するには、「ajax」の要素の差し換えに、上手く再取得を設定する事が必須です。

 

今回も、なんとかこの山を越えました。 次の「Theme Rep」のバージョンで、それを紹介できると思います。