PROGRAMMING
javascript
- ページャーを作る(簡易版)
- ページャーを作る 4/4
(クロスブラウザ対策)
(ページャー表示用メソッド)
(ページャーの使い方) - ページャーを作る 3/4
(イベント登録) - ページャーを作る 2/4
(スタイルの設定) - ページャーを作る 1/4
(ページャー用関数を準備)
(各要素を生成) - 自作カレンダーを作る 6/6
(11.~14.各種メソッド)
(15.簡単な使い方) - 自作カレンダーを作る 5/6
(09.祝休日の判定)
(10.閏年の判定) - 自作カレンダーを作る 4/6
(08.イベントの設定) - 自作カレンダーを作る 3/6
(07.スタイルの設定) - 自作カレンダーを作る 2/6
(05.カレンダーのマスのみ作成)
(06.各マスへ年月・日付を埋め込み) - 自作カレンダーを作る 1/6
(01.カレンダーの基を準備)
(02.各月の日数や年月日の区切り文字)
(03.前月・次月指定時の処理)
(04.前月・次月部分の年月を算出) - JS-Image-Resizerを使って画像を高画質で縮小
- ファイルを作成しローカルに保存
- モーダルウィンドウをクラス化
- ストップウォッチを作る
- XMLHttpRequest Lebel2を試してみる
- jQuery:Tableで親・子・兄弟要素を取得
- 文字列をセパレータ文字で分割し配列で返す関数
- forループのカウンタを使用している関数の定義
- クロージャの使いどころ
- JSONPでクロスドメイン
- AjaxでJSON形式のデータを扱う
- jsファイルからjsファイルを呼び出す
- jQuery:モーダルウィンドウを作ってみる
CSS
- フォルダ構成をCSSで見やすくする
- シンタックスハイライトPrismのカスタマイズ
- リスト(li)を中央に配置する
- ブロックレベル要素全体をリンクにする
- 実践と点線の交わり部分のギザギザをすっきりさせる
PHP
Java
- IntelliJ.Gradle.JavaFX(6) プラグイン org.beryx.jlink を使ってみる
- IntelliJ.Gradle.JavaFX(5) NSISでインストーラーを作る
- IntelliJ.Gradle.JavaFX(4) exewrapで実行可能jarをexe化する
- IntelliJ.Gradle.JavaFX(3) Jlink でカスタム JRE を作る
- IntelliJ.Gradle.JavaFX(2) すべての依存対象を含んだ Fatjar を作る
- IntelliJ.Gradle.JavaFX(1) アプリケーションを作る
- javaのコンパイルと実行
- イメージを回転する
- Exif情報を簡単に取得できるライブラリ
- 高画質で画像縮小
- JDBCによるデータベース操作
ページャーを作る
サイトを構築していると必ずといっていいほどページャーが必要になってきます。
ブログなど日常的にコンテンツが増えるていくページは、ページ分けしなければ下にどんどん長くなり、非常に見ずらいものになります。
そこで、汎用性のあるページャーを作ってみました。
-----2015.02.06(修正)-----
ページ数が多くなると希望のページへの移動が難しくなるので、中央部のページを10件単位でプラスマイナスできるように修正しました。
後、不要なコードなどもありましたので整理しました。
-----2015.06.21(修正)-----
イベント登録のページ番号クリックで、先頭ページと最終ページをクリックした場合、中央のページ番号をそれぞれクリックした側に寄せられるように
修正しました。例えば、先頭ページ(1ページ)の場合はクリックしたら中央ページ番号が2ページから始まるように。(イベント登録 186行~199行追加)
MkenPagerのダウンロード(mkenPager.js)
mkenPager.zip
ページャー用関数を準備
最初にページャー用の関数を準備します。この関数にイベントやスタイルなどを追加していきます。
var MkenPager = function(tagId, totalRow, viewCount){
// ページャーの表示されるタグ
this.tagId = tagId;
// データの総件数
this.totalRow = Number(totalRow);
// 1ページに表示する件数
this.viewCount = Number(viewCount);
// 現在選択されているページの先頭データの行番号
this.currentRow = 1;
// 最終ページ番号
this.lastPageNum = Math.ceil(this.totalRow / this.viewCount);
};
引数を3個とる関数です。それぞれの引数の意味は、次のとおりです。
1. tagId:ページャーが表示されるHTMLタグのidです(例:<div id="paging"></div>)
2. totalRow:表示するデータの総件数です。
3. viewCount:1ページに表示したい件数です。
プロパティやメソッドの追加(各要素を生成)
前記の関数MkenPagerにプロパティやメソッドを追加していきます。プロトタイプ定義をオブジェクト形式で追加しています。
まずは各要素の生成です。
MkenPager.prototype = {
createHTML: function(){
// ページャーを囲む枠
var htmlStr = '<div id="' + this.tagId + 'Pager">';
// 前へボタン(子の空のdivは三角)
htmlStr += '<div id="' + this.tagId + 'Prev"><div></div></div>';
// マイナスボタン(中央部のページを10件マイナスする)
htmlStr += '<div id="' + this.tagId + 'Minus">-</div>';
// ページ表示部
htmlStr += '<ul id="' + this.tagId + 'PageNumGroup">';
// ページ番号を作成
var tmpTotalRow = this.totalRow;
// リストの数は10個で固定
for(var pageNum = 1; pageNum <= 10; pageNum++){
if(tmpTotalRow > 0){
if(pageNum == 10){
htmlStr += '<li>' + this.lastPageNum + '</li>';
}else{
htmlStr += '<li>' + pageNum + '</li>';
}
}else{
htmlStr += '<li class="' + this.tagId + 'nonePage"> </li>';
}
tmpTotalRow = tmpTotalRow - this.viewCount;
}
htmlStr += '</ul>';
// プラスボタン(中央部のページを10件プラスする)
htmlStr += '<div id="' + this.tagId + 'Plus">+</div>';
// 次へボタン(子の空のdivは三角)
htmlStr += '<div id="' + this.tagId + 'Next"><div></div></div>';
htmlStr += '</div>';
// フロートクリア
htmlStr += '<div id="' + this.tagId + 'clear"></div>';
var pagerContainer = document.getElementById(this.tagId);
pagerContainer.innerHTML = htmlStr;
},
プロパティやメソッドの追加(スタイルの設定)
次はスタイルの設定です。長いのでスタイルシートでとも考えましたが、ファイルの扱いも考えコードに埋め込みました。
setStyle: function(){
// 全体を囲むdiv
var pager = document.getElementById(this.tagId + 'Pager');
pager.style.display = "flex"; // floatを使用しない
pager.style.width = "447px";
pager.style.height = "36px";
pager.style.margin = "30px";
pager.style.border = "1px solid rgba(0,128,128,0.5)";
pager.style.borderRadius = "15px";
// 前へボタン
var prev = document.getElementById(this.tagId + 'Prev');
prev.style.width = "26px";
prev.style.height = "26px";
prev.style.margin = "3px 20px";
prev.style.borderRadius = "13px";
prev.style.backgroundColor = "#666666";
prev.style.cursor = "default";
prev.style.opacity = 0.5;
// 前へボタンの三角
var prevChild = prev.firstChild;
prevChild.style.width = "0px";
prevChild.style.height = "0px";
prevChild.style.borderTop = "6px solid transparent";
prevChild.style.borderRight = "10px solid #ffffff";
prevChild.style.borderBottom = "6px solid transparent";
prevChild.style.borderLeft = "10px solid transparent";
prevChild.style.margin = "7px 0 0 -3px";
// 次へボタン
var next = document.getElementById(this.tagId + 'Next');
next.style.width = "26px";
next.style.height = "26px";
next.style.margin = "3px 20px";
next.style.borderRadius = "13px";
next.style.backgroundColor = "#666666";
next.style.cursor = "pointer";
// 次へボタンの三角
var nextChild = next.firstChild;
nextChild.style.width = "0px";
nextChild.style.height = "0px";
nextChild.style.borderTop = "6px solid transparent";
nextChild.style.borderRight = "10px solid transparent";
nextChild.style.borderBottom = "6px solid transparent";
nextChild.style.borderLeft = "10px solid #ffffff";
nextChild.style.margin = "7px 0 0 9px";
// マイナスボタン
var minus = document.getElementById(this.tagId + 'Minus');
minus.style.width = "23px";
minus.style.height = "26px";
minus.style.margin = "4px 0px";
minus.style.textAlign = "center";
minus.style.color = "rgba(0,102,153,0.5)";
minus.style.backgroundColor = "#eee";
minus.style.fontWeight = "bold";
minus.style.fontSize = "14px";
minus.style.border = "1px solid rgba(0,128,128,0.5)";
minus.style.cursor = "default";
// プラスボタン
var plus = document.getElementById(this.tagId + 'Plus');
plus.style.width = "23px";
plus.style.height = "26px";
plus.style.margin = "4px 0px";
plus.style.textAlign = "center";
plus.style.color = "rgba(0,102,153,0.5)";
plus.style.backgroundColor = "#eee";
plus.style.fontWeight = "bold";
plus.style.fontSize = "14px";
plus.style.border = "1px solid rgba(0,128,128,0.5)";
if(this.lastPageNum < 11){
plus.style.cursor = "default";
}else{
plus.style.cursor = "pointer";
}
// 中央部のUL(ページ番号のコンテナ)
var pageNumGroup = document.getElementById(this.tagId + "PageNumGroup");
pageNumGroup.style.width = "271px";
pageNumGroup.style.height = "26px";
pageNumGroup.style.margin = "4px 0";
pageNumGroup.style.textAlign = "center";
pageNumGroup.style.fontSize = "13px";
// ul内のli (ページ番号部)
var nodes = pageNumGroup.childNodes;
for(var i = 0; i < nodes.length; i++){
nodes[i].style.display = "inline-block";
nodes[i].style.width = "23px";
nodes[i].style.height = "26px";
nodes[i].style.margin = "0 1px";
nodes[i].style.paddingTop = "1px";
nodes[i].style.border = "1px solid rgba(0,128,128,0.5)";
nodes[i].style.color = "#006699";
if(i === 0){
nodes[i].style.cursor = "default";
nodes[i].style.backgroundColor = "rgba(130,210,253,0.5)";
}else{
nodes[i].style.cursor = "pointer";
nodes[i].style.backgroundColor = "rgba(130,210,253,0.1)";
}
}
// 1ページ目と最終ページを外側にずらす
nodes[0].style.marginRight = "5px";
nodes[9].style.marginLeft = "5px";
// ページが無い部分のスタイル
var nonePage = document.getElementsByClassName(this.tagId + "nonePage");
for(var i = 0; i < nonePage.length; i++){
nonePage[i].style.borderColor = "#eeeeee";
nonePage[i].style.cursor = "default";
}
},
プロパティやメソッドの追加(イベント登録)
いよいよ難関のイベントです。この部分に何日もかかってしまいました。
setEvent: function(){
// イベントのthisはインスタンスではなくイベントの発生元を指すので
// インスタンスは一旦ローカル変数に代入して使用する
var self = this;
var lastIdx = Math.floor(self.totalRow / self.viewCount);
// ページ番号用リストの最後のIndex
if(lastIdx > 9){lastIdx = 9;}
// 現在選択されているページ番号用リスト(0~9)
var currentIdx = 0;
// 現在選択されているページ番号
var currentPageNum = 1;
var prev = document.getElementById(this.tagId + 'Prev');
var next = document.getElementById(this.tagId + 'Next');
var minus = document.getElementById(this.tagId + 'Minus');
var plus = document.getElementById(this.tagId + 'Plus');
var pageNumGroup = document.getElementById(this.tagId + "PageNumGroup");
var nodes = pageNumGroup.childNodes;
// ページ番号クリック **********
for(var i = 0; i < nodes.length; i++){
this.addListener(nodes[i], "click", function(){
// クリックされたインデックスを取得
var count = 0;
var node = this;
// 直前の兄弟がある限りカウンターを増やすことで自分が何番目かがわかる
while(node.previousSibling) {
++count;
node = node.previousSibling;
}
var oldIdx = currentIdx; // 直前のliインデックス
currentIdx = count;
// 先頭ページの場合、中央のページ番号部分を先頭ページ側に寄せる
if(currentIdx == 0){
for(var j = 1; j <= 8; j++){
nodes[j].childNodes[0].nodeValue = j + 1;
}
}
// 最終ページの場合、中央のページ番号部分を最終ページ側に寄せる
if(currentIdx == 9){
var k = 8;
for(var j = 1; j <= 8; j++){
nodes[j].childNodes[0].nodeValue = self.lastPageNum - k;
k--;
}
}
// ページ番号のstyleを元に戻す
defaultPageStyle(nodes[oldIdx]);
// クリックされたページ番号のstyleを変える
newPageStyle(this);
// 現在のページ番号を取得
getPageNum(this);
// 先頭データ行番号を取得
getTopRowNum();
// ボタンスタイル変更
btnStyle(prev, 0);
btnStyle(next, lastIdx);
});
}
// 前へボタンクリック **********
this.addListener(prev, 'click', function(){
if(currentIdx == 0){ // 先頭ページなら何もしない
return;
}else{
// ページ番号のstyleを元に戻す
defaultPageStyle(nodes[currentIdx]);
// 最初と2番目リストのページ差が2ページ以上ある場合は
// 最初と最後を除いた中央部のリストのページ番号を減らす
if((currentIdx == 1) && ((currentPageNum - 1) >= 2)){
for(var i = 1; i <= 8; i++){
var pageNum = Number(nodes[i].childNodes[0].nodeValue);
nodes[i].childNodes[0].nodeValue = pageNum - 1;
}
}else{
// インデックスを減らす
currentIdx--;
}
// ページ番号の新スタイル
newPageStyle(nodes[currentIdx]);
// 現在のページ番号を取得
getPageNum(nodes[currentIdx]);
// 先頭データ行番号を取得
getTopRowNum();
}
// ボタンスタイル変更
btnStyle(prev, 0);
next.style.cursor = "pointer";
next.style.opacity = 1;
// プラスマイナスのカーソル変更
plusMinusStyle();
});
// 次へボタンクリック **********
this.addListener(next, 'click', function(){
if(currentIdx == lastIdx){ // 最終ページなら何もしない
return;
}else{
// ページ番号のstyleを元に戻す
defaultPageStyle(nodes[currentIdx]);
// 最初と最後を除いたリストのページ番号を増やす
//(最後とその前のリストのページ差が2ページ以上の場合)
if((currentIdx == 8) && ((self.lastPageNum - currentPageNum) >= 2)){
for(var i = 1; i <= 8; i++){
var pageNum = Number(nodes[i].childNodes[0].nodeValue);
nodes[i].childNodes[0].nodeValue = pageNum + 1;
}
}else{
// インデックスを増やす
currentIdx++;
}
// ページ番号の新スタイル
newPageStyle(nodes[currentIdx]);
// 現在のページ番号を取得
getPageNum(nodes[currentIdx]);
// 先頭データ行番号を取得
getTopRowNum();
}
// ボタンスタイル変更
btnStyle(next, lastIdx);
prev.style.cursor = "pointer";
prev.style.opacity = 1;
// プラスマイナスのカーソル変更
plusMinusStyle();
});
// マイナスボタンクリック **********
this.addListener(minus, 'click', function(){
var node1Val = Number(nodes[1].childNodes[0].nodeValue);
// 2番目のページ番号から10を差し引いた結果が2ページ未満の場合
if((node1Val - 10) < 2){
// 3ページから11ページならば中央部のページ番号を1ページ側にずらす
if(node1Val > 2 && node1Val < (2 + 10)){
for(var i = 1; i <= 8; i++){
var pageNum = Number(nodes[i].childNodes[0].nodeValue);
nodes[i].childNodes[0].nodeValue = pageNum - (node1Val - 2);
}
// それ以外は何もしない
}else{
return;
}
}else{
// 最初と最後を除いた中央部のリストのページ番号を10づつ減らす
for(var i = 1; i <= 8; i++){
var pageNum = Number(nodes[i].childNodes[0].nodeValue);
nodes[i].childNodes[0].nodeValue = pageNum - 10;
}
}
// 現在のページ番号を取得
getPageNum(nodes[currentIdx]);
// 先頭データ行番号を取得
getTopRowNum();
// プラスマイナスのカーソル変更
plusMinusStyle();
});
// プラスボタンクリック **********
this.addListener(plus, 'click', function(){
var node8Val = Number(nodes[8].childNodes[0].nodeValue);
// ページ数が10に満たない場合
if(lastIdx < 9){
return;
}
// 9番目のページ番号に10を足した結果が最後から1ページ前のページ番号を超える場合
if((node8Val + 10) > (self.lastPageNum - 1)){
// 9番目のページ番号が(最終ページ番号-10)から(最終ページ-2)の間ならば
// 中央部のページ番号を最終ページ側にずらす
if(node8Val >= (self.lastPageNum - 10)
&& node8Val <= (self.lastPageNum -2)){
for(var i = 1; i <= 8; i++){
var pageNum = Number(nodes[i].childNodes[0].nodeValue);
nodes[i].childNodes[0].nodeValue =
pageNum + ((self.lastPageNum - 1) - node8Val);
}
// それ以外は何もしない
}else{
return;
}
}else{
// 最初と最後を除いた中央部のリストのページ番号を10づつ増やす
for(var i = 1; i <= 8; i++){
var pageNum = Number(nodes[i].childNodes[0].nodeValue);
nodes[i].childNodes[0].nodeValue = pageNum + 10;
}
}
// 現在のページ番号を取得
getPageNum(nodes[currentIdx]);
// 先頭データ行番号を取得
getTopRowNum();
// プラスマイナスのカーソル変更
plusMinusStyle();
});
// 関数:既定のページ番号のスタイル
function defaultPageStyle(node) {
node.style.cursor = "pointer";
node.style.backgroundColor = "rgba(130,210,253,0.1)";
}
// 関数:新たに適用するページ番号のスタイル
function newPageStyle(node) {
node.style.cursor = "default";
node.style.backgroundColor = "rgba(130,210,253,0.5)";
}
// 関数:ボタンスタイル変更
function btnStyle(node, nodeIdx) {
if(currentIdx == nodeIdx){
node.style.cursor = "default";
node.style.opacity = 0.5;
}else{
node.style.cursor = "pointer";
node.style.opacity = 1;
}
}
// 関数:プラスマイナスのカーソル変更
function plusMinusStyle(){
var node1 = Number(nodes[1].childNodes[0].nodeValue);
var node8 = Number(nodes[8].childNodes[0].nodeValue);
var node9 = Number(nodes[9].childNodes[0].nodeValue);
if(node1 - 1 == 1){
minus.style.cursor = "default";
}else{
minus.style.cursor = "pointer";
}
if(node9 - node8 == 1){
plus.style.cursor = "default";
}else{
plus.style.cursor = "pointer";
}
}
// 関数:現在のページ番号を取得
function getPageNum(node) {
var txtNode = node.childNodes[0];
currentPageNum = Number(txtNode.nodeValue);
}
// 関数:先頭データ行番号を取得
function getTopRowNum() {
self.currentRow = 1 + (currentPageNum - 1) * self.viewCount;
}
},
プロパティやメソッドの追加(イベントのクロスブラウザ対策)
おきまりのIE対策。
addListener: function(elm, ev, listener){
if(elm.addEventListener) { // IE以外
elm.addEventListener(ev, listener, false);
} else if(elm.attachEvent) { // IE
elm.attachEvent('on' + ev, listener);
} else {
throw new Error('イベントリスナーに未対応です。');
}
},
プロパティやメソッドの追加(ページャー表示用メソッド)
いままでのメソッドを集めて、ひとつのページャー表示用メソッドにしてあります。
インスタンスの後にこのメソッドを呼び出してページャーを使用します。
showPager: function(){
this.createHTML(); // 各要素を生成
this.setStyle(); // スタイルをセット
this.setEvent(); // イベントをセット
}
ページャーの使い方
このページのページャーサンプルではidがpagingのdivに表示させています。
データの件数は100件、1ページの表示件数は7件で呼び出ししています。
<head>
<meta charset="UTF-8">
<title>団塊爺ちゃんの備忘録</title>
<link rel="stylesheet" href="index.css">
<script src="jquery-1.8.0.min.js"></script>
<script src="mkenPager.js"></script>
<script src="index.js"></script>
</head>
<body>
<div id="paging"></div> <!--ページャーの表示場所-->
var tagId = "paging";
// データの総件数が100件で1ページに7件づつ表示の場合
var pager = new MkenPager(tagId, 100, 7);
// ページャーの表示
pager.showPager();
// ここからページャー用イベント
// 各ページをクリック
$("#" + tagId + " li").on("click", function(){
action();
});
// 「前へ」ボタンクリック
$("#" + tagId + "Prev").on("click", function(){
action();
});
// 「次へ」ボタンクリック
$("#" + tagId + "Next").on("click", function(){
action();
});
// マイナスボタンクリック
$("#" + tagId + "Minus").on("click", function(){
action();
});
// プラスボタンクリック
$("#" + tagId + "Plus").on("click", function(){
action();
});
function action(){
var msg = 'このページの先頭の行番号は'+pager.currentRow +'行目です。';
alert(msg);
}
7行目から下がページャーのイベントで、jQueryでイベントを追加しています。
アプリ側で必要なデータはページャーの各プロパティから取得します。
ページの先頭の行番号:pager.currentRow
などです。