Blogger:ページ番号付ページナビ(10)ボタンの折り返し表示をやめる

2016-12-09

旧ブログ

t f B! P L
ナビボタンの折り返しはカッコ悪いのでやっぱりやめることにしました。

前の関連記事:Blogger:ページ番号付ページナビ(9)Paginavi2_Bloggerモジュールの導入


flex-grow、flex-shrink、flex-basisのお勉強


折り返しをなくすためにはボタンをすべて一行で表示させないといけません。

Flexboxを使うなら知っておきたい「flexアイテム」の幅の計算方法 – Rriverを読んでflex-grow、flex-shrink、flex-basisの関係がわかりました。

CSS3 Flexbox の各プロパティの使い方をヴィジュアルで詳しく解説 | コリスで紹介されているVisual Guide to CSS3 Flexbox: Flexbox Playground |を使って試してみても思った通りに動きました。

flex-grow、flex-shrink、flex-basisはflexboxのアイテムにそれぞれ設定するプロパティです。

flex-growはアイテムの合計pxがコンテナの合計pxより小さい時に影響力を発揮し、余剰pxの分配率を表します。

$$\rm(分配されるpx)=\dfrac {(flexGrow値)} { (flexGrow値の和)}\times  (余剰px)$$
つまりアイテムの合計pxより余っているコンテナのpxがflex-grow値の比で分配されることになります。

flex-shrinkはflex-growと逆で不足したpxをflex-shrink値の比で分配します。

コンテナのpxを不足させるためには、アイテムのpxの合計がコンテナのpxを上回らないといけません。

ということでflex-basisで各アイテムに最初の幅を設定するのがflex-basisになります。

flex-basisのpxの和がコンテナのpxを上回るとその不足分をflex-shrinkの比で分配して差し引きます。

と、いうことまで理解できましたがページナビを思ったように縮小して表示することはできませんでした。


モバイルバージョンで両端のボタンが一部欠けてしまいます。

ちょっといろいろしてみましたが解決できなかったのでこの方法は断念しました。

transformで水平方向に縮小する


iPod touch6 の縦方向で二桁までの表示は水平方向に0.9倍すると収まったのでもうそれで満足することにしました。
// PageNavi2_Bloggerモジュール
var PageNavi2_Blogger = PageNavi2_Blogger || function() {
    var pg = {  // グローバルスコープに出すオブジェクト。グローバルスコープから呼び出すときはPageNavi2_Bloggerになる。
        defaults : {  // 既定値。
            "perPage" : 10, //1ページあたりの投稿数。
            "numPages" : 5  // ページナビに表示する通常ページボタンの数。スタートページからエンドページまで。
        },
        callback : {  // フィードを受け取るコールバック関数。
            getURL : function(root){  // フィードからタイムスタンプを得て表示させるURLを作成してそこに移動する。
                var post = root.feed.entry[0];  // フィードから先頭の投稿を取得。
                var m = /(\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d)\.\d\d\d(.\d\d:\d\d)/i.exec(post.published.$t);
                var timestamp = encodeURIComponent(m[1] + m[2]);  // 先頭の投稿からタイプスタンプを取得。
                var addr_label = "/search/label/" + vars.postLabel + "?updated-max=" + timestamp + "&max-results=" + vars.perPage + "#PageNo=" + vars.pageNo;
                var addr_page = "/search?updated-max=" + timestamp + "&max-results=" + vars.perPage + "#PageNo=" + vars.pageNo; 
                location.href =(vars.postLabel)?addr_label:addr_page;  // ラベルインデックスページとインデックスページでURLが異なることへの対応。
            }, 
            getTotalPostCount : function(root){ 
                var total_posts = parseInt(root.feed.openSearch$totalResults.$t, 10);  // 取得したフィードから総投稿総数を得る。
                createNodes(total_posts);  // 総投稿数をもとにページナビのボタンを作成する。
            }
        },
        all: function(array_elementIDs) {  // ここから開始する。引数にページナビを置換する要素のidを配列に入れる。
            array_elementIDs.forEach(function(e){
                var elem = document.getElementById(e);  // elementIDの要素の取得。
                if (elem) {vars.elements.push(elem);}  // elementIDの要素を配列に取得。
            });
            if (vars.elements.length > 0) {createPageNavi();}  // ページナビの作成。
        }
    }; // end of pg
    var vars = {  // PageNavi2_Bloggerモジュール内の"グローバル"変数。
        perPage : pg.defaults.perPage,  // デフォルト値の取得。
        numPages : pg.defaults.numPages,  // デフォルト値の取得。
        jumpPages : pg.defaults.numPages, // ジャンプボタンでページ番号が総入れ替えになる設定値。
        postLabel : null,  // ラベル名。
        pageNo : null,  // ページ番号。
        currentPageNo : null,  // 現在のページ番号。
        elements : []  // ページナビを挿入するhtmlの要素の配列。
    };
    function redirect(pageNo) {  // ページ番号のボタンをクリックされた時に呼び出される関数。
        vars.pageNo = pageNo;  // 表示するページ番号
        if (pageNo==1) {  // 1ページ目を取得するときはページ番号からURLを算出する必要がない。
            location.href = (!vars.postLabel)?"/":"/search/label/" + vars.postLabel + "?max-results=" + vars.perPage;  // ラベルページインデックスの場合分け。
        } else {
            var startPost = (vars.pageNo - 1) * vars.perPage;  // 新たに表示する先頭ページの先頭になる投稿番号を取得。
            var url;
            if (vars.postLabel) {   // ラベルページインデックスの場合分け。
                url = "/feeds/posts/summary/-/" + vars.postLabel + "?start-index=" + startPost + "&max-results=1&alt=json-in-script&callback=PageNavi2_Blogger.callback.getURL";
            } else {
                url = "/feeds/posts/summary?start-index=" + startPost + "&max-results=1&alt=json-in-script&callback=PageNavi2_Blogger.callback.getURL";
            }
            writeScript(url);  //スクリプト注入。
        }
    }
    function createElem(tag){  // tagの要素を作成して返す。
       return document.createElement(tag); 
    }   
    function createNodes(total_posts) {  // 総投稿数からページナビのボタンを作成。
        var buttunElems = []; // ボタン要素を入れる配列。
        var numPages = vars.numPages;  // ページナビに表示するページ数。
        var prevText = '\u00ab';  // 左向きスキップのための矢印。
        var nextText = '\u00bb';  // 右向きスキップのための矢印。
        var diff =  Math.floor(numPages / 2);  // スタートページ - 現在のページ = diff。
        var pageStart = vars.currentPageNo - diff;  // スタートページの算出。
        if (pageStart < 1) {pageStart = 1;}  // スタートページが1より小さい時はスタートページを1にする。
        var lastPageNo = Math.ceil(total_posts / vars.perPage); // 総投稿数から総ページ数を算出。
        var pageEnd = pageStart + numPages - 1;  // エンドページの算出。
        if (pageEnd > lastPageNo) {pageEnd = lastPageNo;} // エンドページが総ページ数より大きい時はエンドページを総ページ数にする。
        if (pageStart > 1) {buttunElems.push(createButton(1,1));}  // スタートページが2以上のときはスタートページより左に1ページ目のボタンを作成する。
        if (pageStart == 3) {buttunElems.push(createButton(2, 2));} // スタートページが3のときはジャンプボタンの代わりに2ページ目のボタンを作成する。
        if (pageStart > 3) {  // スタートページが4以上のときはジャンプボタンを作成する。
            var prevNumber = pageStart - vars.jumpPages + diff;  // ジャンプボタンでジャンプしたときに表示するページ番号。
            (prevNumber < 2)?buttunElems.push(createButton(1,prevText)):buttunElems.push(createButton(prevNumber, prevText));  // ページ番号が1のときだけボタンの作り方が異なるための場合分け。
        }
        for (var j = pageStart; j <= pageEnd; j++) {buttunElems.push((j == vars.currentPageNo)?createCurrentNode(j):createButton(j, j));}  // スタートボタンからエンドボタンまで作成。
        if (pageEnd == lastPageNo - 2) {buttunElems.push(createButton(lastPageNo - 1, lastPageNo - 1));}  // エンドページと総ページ数の間に1ページしかないときは右ジャンプボタンは作成しない。
        if (pageEnd < (lastPageNo - 2)) {  // エンドページが総ページ数より3小さい時だけ右ジャンプボタンを作成。
            var nextnumber = pageEnd + 1 + diff;  // ジャンプボタンでジャンプしたときに表示するページ番号。
            if (nextnumber > lastPageNo) {nextnumber = lastPageNo;} // 表示するページ番号が総ページ数になるときは総ページ数の番号にする。
            buttunElems.push(createButton(nextnumber, nextText));  // 右ジャンプボタンの作成。
        }
        if (pageEnd < lastPageNo) {buttunElems.push(createButton(lastPageNo, lastPageNo));}  // 総ページ番号ボタンの作成。
        writeHtml(buttunElems);  // htmlの書き込み。
    }
    function createPageNavi() {  // URLからラベル名と現在のページ番号を得、その後総投稿数を得るためのフィードを取得する。
        var thisUrl = location.href;  // 現在表示しているURL。
        if (/\/search\/label\//i.test(thisUrl)) {  // ラベルインデックスページの場合URLからラベル名を取得。
            vars.postLabel = /\/search\/label\/(.+)(?=\?)/i.exec(thisUrl)[1];  // 後読みは未実装の可能性あるので使わない。
        } 
        if (!/\?q=|\.html$/i.test(thisUrl)) {  // 検索結果や固定ページではないとき。
            vars.currentPageNo = (/#PageNo=/i.test(thisUrl))?/#PageNo=(\d+)/i.exec(thisUrl)[1]:1;  // URLから現在のページ番号の取得。
            var url;  // フィードを取得するためのURL。
            if (vars.postLabel) {  // 総投稿数取得のためにフィードを取得するURLの作成。ラベルインデックスのときはそのラベル名の総投稿数を取得するため。
                url = '/feeds/posts/summary/-/' + vars.postLabel + "?alt=json-in-script&callback=PageNavi2_Blogger.callback.getTotalPostCount&max-results=1";          
            } else {
                url = "/feeds/posts/summary?max-results=1&alt=json-in-script&callback=PageNavi2_Blogger.callback.getTotalPostCount";
            }
            writeScript(url); 
        }
    }   
    function createButton(pageNo, text) {  // redirectするボタンのノード作成。
        var spanNode = createElem('div');
        spanNode.className = "displaypageNum";
        spanNode.appendChild(createElem('a'));
        spanNode.firstChild.textContent = text;
        spanNode.firstChild.href = "#";
        spanNode.firstChild.name = pageNo;  // redirect()の引数に使う。
        return spanNode;
    }
    function createCurrentNode(j) {  // 現在表示中のページのノード作成。
        var spanNode = createElem('div');
        spanNode.className = "pagecurrent"; 
        spanNode.textContent = j;
        return spanNode;
    }
    function writeScript(url) {  // スクリプト注入。
        var ws = createElem('script');
        ws.type = 'text/javascript';
        ws.src = url;
        document.getElementsByTagName('head')[0].appendChild(ws);
    }
    function onclickEvent(e) {  // Event bubblingで発火させる関数。
        e=e||event; // IE sucks
        var target = e.target||e.srcElement; // targetはaになる。// and sucks again // target is the element that has been clicked
        if (target && target.parentNode.className=="displaypageNum") {
            redirect(target.name);
            return false; // stop event from bubbling elsewhere
        }
    }
    function writeHtml(buttunElems) {  // htmlの書き込み。
        var divNode = createElem('div');       
        buttunElems.forEach(function(b){
            divNode.appendChild(b);
        });  // ボタンノードを新しいdivノードの子ノードに追加する。
        divNode.style.padding = "0px 10px";
        divNode.style.display = "flex";  // flexの子要素はdivにする。spanはダメ。
        divNode.style.justifyContent = "center";  // ボタンを中央寄せにする
        divNode.style.alignItems = "center";  // これがないと現在のページのボタンがずれる。
        divNode.style.transform = "scaleX(0.9)";  // 水平方向に0.9倍にする。
        var dupNode;
        vars.elements.forEach(function(elem){
            dupNode = divNode.cloneNode(true);  // ボタンノードを子ノードとするdivノードを複製する。デフォルトのプロパティしかコピーされない。イベントもコピーされない。
            dupNode.onclick = onclickEvent;  // 複製したノードにイベントのプロパティを追加する。
            elem.appendChild(dupNode);   // 既存のノードに追加して表示させる。
        });  
    }
    return pg;  // グローバルスコープにだす。
}();
//デフォルト値を変更したいときは以下のコメントアウトをはずして設定する。
//PageNavi2_Blogger.defaults["perPage"] = 10 //1ページあたりの投稿数。
//PageNavi2_Blogger.defaults["numPages"] = 5 // ページナビに表示するページ数。
PageNavi2_Blogger.all(["blog-pager","blog-pager2"]);  // ページナビの起動。引き数にHTMLの要素のidを配列で入れる。
ページ番号が3桁になったときは両端のページボタンの一部が欠けます。


CSSも少し変更しました。

Closure CompilerとClosure StylesheetsでJavaScriptとCSSをそれぞれ圧縮する


linuxBean14.04(126)Closure CompilerでJavaScriptを圧縮するのClosure Compilerを使ってPageNavi2_Blogger.jsを圧縮します。

java -jar ~/closure-compiler/compiler.jar --js PageNavi2_Blogger.js  --js_output_file PageNavi2_Blogger.min.js

このコマンドで圧縮できました。
var PageNavi2_Blogger=PageNavi2_Blogger||function(){function l(){var a=location.href;/\/search\/label\//i.test(a)&&(c.postLabel=/\/search\/label\/(.+)(?=\?)/i.exec(a)[1]);/\?q=|\.html$/i.test(a)||(c.currentPageNo=/#PageNo=/i.test(a)?/#PageNo=(\d+)/i.exec(a)[1]:1,k(c.postLabel?"/feeds/posts/summary/-/"+c.postLabel+"?alt=json-in-script&callback=PageNavi2_Blogger.callback.getTotalPostCount&max-results=1":"/feeds/posts/summary?max-results=1&alt=json-in-script&callback=PageNavi2_Blogger.callback.getTotalPostCount"))}
function f(a,b){var c=document.createElement("div");c.className="displaypageNum";c.appendChild(document.createElement("a"));c.firstChild.textContent=b;c.firstChild.href="#";c.firstChild.name=a;return c}function m(a){var b=document.createElement("div");b.className="pagecurrent";b.textContent=a;return b}function k(a){var b=document.createElement("script");b.type="text/javascript";b.src=a;document.getElementsByTagName("head")[0].appendChild(b)}function n(a){a=a||event;if((a=a.target||a.srcElement)&&
"displaypageNum"==a.parentNode.className)return a=a.name,c.pageNo=a,1==a?location.href=c.postLabel?"/search/label/"+c.postLabel+"?max-results="+c.perPage:"/":(a=(c.pageNo-1)*c.perPage,k(c.postLabel?"/feeds/posts/summary/-/"+c.postLabel+"?start-index="+a+"&max-results=1&alt=json-in-script&callback=PageNavi2_Blogger.callback.getURL":"/feeds/posts/summary?start-index="+a+"&max-results=1&alt=json-in-script&callback=PageNavi2_Blogger.callback.getURL")),!1}function p(a){var b=document.createElement("div");
a.forEach(function(a){b.appendChild(a)});b.style.padding="0px 5px";b.style.display="flex";b.style.justifyContent="center";b.style.alignItems="center";b.style.transform="scaleX(0.9)";var d;c.elements.forEach(function(a){d=b.cloneNode(!0);d.onclick=n;a.appendChild(d)})}var h={defaults:{perPage:10,numPages:5},callback:{getURL:function(a){a=/(\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d)\.\d\d\d(.\d\d:\d\d)/i.exec(a.feed.entry[0].published.$t);var b=encodeURIComponent(a[1]+a[2]);a="/search/label/"+c.postLabel+"?updated-max="+
b+"&max-results="+c.perPage+"#PageNo="+c.pageNo;b="/search?updated-max="+b+"&max-results="+c.perPage+"#PageNo="+c.pageNo;location.href=c.postLabel?a:b},getTotalPostCount:function(a){var b=parseInt(a.feed.openSearch$totalResults.$t,10);a=[];var d=c.numPages,g=Math.floor(d/2),e=c.currentPageNo-g;1>e&&(e=1);b=Math.ceil(b/c.perPage);d=e+d-1;d>b&&(d=b);1<e&&a.push(f(1,1));3==e&&a.push(f(2,2));if(3<e){var h=e-c.jumpPages+g;2>h?a.push(f(1,"\u00ab")):a.push(f(h,"\u00ab"))}for(;e<=d;e++)a.push(e==c.currentPageNo?
m(e):f(e,e));d==b-2&&a.push(f(b-1,b-1));d<b-2&&(g=d+1+g,g>b&&(g=b),a.push(f(g,"\u00bb")));d<b&&a.push(f(b,b));p(a)}},all:function(a){a.forEach(function(a){(a=document.getElementById(a))&&c.elements.push(a)});0<c.elements.length&&l()}},c={perPage:h.defaults.perPage,numPages:h.defaults.numPages,jumpPages:h.defaults.numPages,postLabel:null,pageNo:null,currentPageNo:null,elements:[]};return h}();PageNavi2_Blogger.all(["blog-pager","blog-pager2"]);

今度はlinuxBean14.04(128)Closure StylesheetsでCSSを圧縮するのClosure StylesheetsでCSSを圧縮します。

closure-stylesheets.jarがなぜか保存されていなかったのでReleases · google/closure-stylesheetsから1.4.0をダウンロードして~/closure-compilerフォルダに保存しました。

java -jar ~/closure-compiler/closure-stylesheets.jar pagenavi.css > pagenavi.min.css

これで圧縮できました。
#blog-pager,#blog-pager2{clear:both}.blog-pager{background:none}.displaypageNum a,.showpage a{padding:5px 10px;margin:6px 2px;color:#fff;background-color:#2973fc;-webkit-box-shadow:0 5px 3px -1px rgba(50,50,50,0.53);-moz-box-shadow:0 5px 3px -1px rgba(50,50,50,0.53);box-shadow:0 5px 3px -1px rgba(50,50,50,0.53)}.pagecurrent{padding:5px 10px;margin:6px 2px;-webkit-box-shadow:0 5px 3px -1px rgba(50,50,50,0.53);-moz-box-shadow:0 5px 3px -1px rgba(50,50,50,0.53);box-shadow:0 5px 3px -1px rgba(50,50,50,0.53)}.displaypageNum a:hover,.showpage a:hover{background:#000;text-decoration:none;color:#fff}.pagecurrent{background:#000;text-decoration:none}#blog-pager .showpage,#blog-pager,.pagecurrent{font-weight:bold;color:#fff}#blog-pager .pages{border:#2973fc;-webkit-box-shadow:0 5px 3px -1px rgba(50,50,50,0.53);-moz-box-shadow:0 5px 3px -1px rgba(50,50,50,0.53);box-shadow:0 5px 3px -1px rgba(50,50,50,0.53)}#blog-pager a{margin:0 5px 0 0;padding:2px 10px 3px;text-decoration:none;color:#fff;background:#2973fc;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;-o-transition:all .3s ease-in;transition:all .3s ease-in}#blog-pager a:hover{color:#fff;text-decoration:none;background:#000}#blog-pager-older-link,#blog-pager-newer-link{float:none}
これらをHTML/JavaScriptガジェットに入れました。

これでPageNavi2_Bloggerモジュールの導入完了です。

参考にしたサイト


Flexboxを使うなら知っておきたい「flexアイテム」の幅の計算方法 – Rriver
これを読んでflex-grow、flex-shrink、flex-basisの関係がわかりました。

CSS3 Flexbox の各プロパティの使い方をヴィジュアルで詳しく解説 | コリス
flexboxについてコンテナとアイテムにわけてのプロパティの解説がわかりやすいです。

Visual Guide to CSS3 Flexbox: Flexbox Playground |
上記のサイトで紹介されているflex-grow、flex-shrink、flex-basisの動作確認できるツール。

LaTeXコマンド集 - 書体
LaTeXの書体コマンド一覧。

Releases · google/closure-stylesheets
closure-stylesheets.jar

次の関連記事:Blogger:ページ番号付ページナビ(11)Paginavi2_Bloggerモジュールの修正

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ