はてなブログ:トップページに「前に戻る」を実装する(やや失敗)

そろそろこのサイトのデザインを変えようかと思い始めての tips チップス(6)。

ブログのトップページは一般的に新着記事を何件か表示するようになっています。はてなブログも、表示形式は一覧と全文形式がありますがどちらも最大15件まで表示できます。

で、その表示件数以降を見るために「次のページ」というリンクがあるわけですが、「前のページ」に戻るためのリンクがありません。この「前のページ」のリンクを作ろうという話です。



過去の試み

この問題、実は過去に2度試みて、実装可能になっています。


Web Storage API

ひとつは、Web Storage API というクッキーと同じような仕様を使ってブラウザのローカルに前のページの履歴を残す方法


www.imuza.com


History.back()

そしてもうひとつは、単純に History.back() という Javascript のメソッドを使う方法です。


www.imuza.com


URLクエリ

で、今回思いついたのは URLクエリに現在表示しているページの URLクエリを次のページのリンクに付加する方法です。


しかし、この方法には決定的な問題があります(笑)。


ひとつ前のページにしか戻れないことです。この方法は、次のページに現在ページの前のページのリンク先を送りますので次のページから現在のページに戻ることはできてもその時にはもう前のページのリンク先がどこにもなくなっています。

ちょっと冷静に考えれば当たり前のことですが気づきませんでした(涙)。


Javascript

で、そこそこ苦労してコードを書いてしまいました(涙)。

記録のために残しておこうと思います。


(function(){
    if(document.body.classList.contains('page-index')){   // トップページ
        const parameter = [];
        const query = location.search.substring(1).split('&');
        for(let i=0; query[i]; i++) {
            const array = query[i].split('=');
            parameter[array[0]] = array[1];
        }

        if(parameter.page !== undefined){
            const next = document.getElementsByClassName('pager-next')[0];
            if(next !== undefined){
                const nextA = next.children[0];
                nextA.href = nextA.href + '&prev=' + parameter.page;
            }

            const elmSpan = document.createElement('span');
            elmSpan.classList.add('pager-prev');
            const elmA = document.createElement('a');
            elmA.textContent = '前のページ';

            if(parameter.prev !== undefined){
                elmA.href = location.origin + '?page=' + parameter.prev;
            }else{
                elmA.href = location.origin;
            }
            elmSpan.appendChild(elmA);

            let pager = document.getElementsByClassName('pager')[0];
            if(pager === undefined){
                pager = document.createElement('div');
                pager.classList.add('pager', 'autopagerize_insert_before');
                pager.appendChild(elmSpan);
            }else{
                pager.insertBefore(elmSpan, pager.firstChild);
            }
            document.getElementById('main-inner').appendChild(pager);
        }
    }
})();