前回(JavaScript/PageNavi(1))の改良版です。前/次で辿っていき、端っこまで来た時にも(CSSでごまかしているとはいえ)リンクのままは気持ち悪い、ということでどうしようかと弄っているうちに、かなり書き換わってしまいました。
というわけで、「前へ」「次へ」のリンク状態/端っこの時の非リンク状態をオブジェクトのメンバに持たせるようにしちゃいました。リンクのクリックイベントについてはライブラリ側で動的に設定してしまいます。
JsPrevNextPager.js :
/**
* JavaScript "Previous", "Next" Page Navigation class library
*
* @author sakamoto-gsyc-3s@glamenv-septzen.net
*/
/**
* JsPrevNextPager container and accessor
*
* @param string identifier
* @return object JsPrevNextPager
*/
var JsPrevNextPager = function(id) {
if (!arguments.callee.pagers) {
arguments.callee.pagers = {};
}
if (!(id in arguments.callee.pagers)) {
arguments.callee.pagers[id] = new JsPrevNextPager.instanciate(id);
}
return arguments.callee.pagers[id];
};
/**
* JsPrevNextPager
*
* @constructor
* @param string identifier
* @return object JsPrevNextPager
*/
JsPrevNextPager.instanciate = function(id_) {
/** identifier */
this.id = id_;
/** pages count */
this.all = 0;
/** current page */
this.current = 1;
/** (X)HTML DOM ID for current page number */
this.id_pageno_cur = 'pageno_cur';
/** (X)HTML DOM ID PREFIX for page block element */
this.id_eachpage = 'page_';
/** (X)HTML DOM ID for previous link (<span> element recommended) */
this.id_prev = 'page_prev';
/** (X)HTML DOM ID for next link (<span> element recommended) */
this.id_next = 'page_next';
/** HTML content for plain next link */
this.plain_next = 'Next Page';
/** HTML content for plain previous link */
this.plain_prev = 'Prev Page';
/** HTML content for active next link */
this.link_next = '<a href="javascript:void(0);">Next Page</a>';
/** HTML content for active previous link */
this.link_prev = '<a href="javascript:void(0);">Prev Page</a>';
/**
* @private
* @return boolean true if there's more 'next' page.
* false if there's no more 'next' page.
*/
this.nextok = function() {
if (2 > this.all) {
return false;
}
if (this.current == this.all) {
return false;
}
return true;
};
/**
* @private
* @return boolean true if there's more 'previous' page.
* false if there's no more 'previous' page.
*/
this.prevok = function() {
if (2 > this.all) {
return false;
}
if (1 == this.current) {
return false;
}
return true;
};
/**
* increment page and update this.current member.
*
* @private
* @return integer updated page position.
*/
this.calcnext = function() {
var cur = this.current;
cur++;
if (cur <= this.all) {
this.current = cur;
}
return cur;
};
/**
* decrement page and update this.current member.
*
* @private
* @return integer updated page position.
*/
this.calcprev = function() {
var cur = this.current;
cur--;
if (1 <= cur) {
this.current = cur;
}
return cur;
};
/**
* toggle page blocks visibility
*
* @private
* @param integer old page num (set to invisible)
* @param integer new page num (set to visible)
*/
this.toggle_pageblock = function(oldnum, newnum) {
var id = null;
if (oldnum == newnum) {
return;
}
$('#' + this.id_pageno_cur).text(newnum);
$('#' + this.id_eachpage + oldnum).hide();
$('#' + this.id_eachpage + newnum).show();
};
/**
* 'Previous' link click event handler
*
* @private
*/
this.clickprev = function() {
this.toggle_pageblock(this.current, this.calcprev());
this.update_navilinks();
};
/**
* 'Next' link click event handler
*
* @private
*/
this.clicknext = function() {
this.toggle_pageblock(this.current, this.calcnext());
this.update_navilinks();
};
/**
* initialize and update 'Previous'/'Next' link.
*/
this.update_navilinks = function() {
var curr_id = this.id;
var obj_prev = $('#' + this.id_prev);
var obj_next = $('#' + this.id_next);
if (this.all < 2) {
// only one page is.
obj_prev.html(this.plain_prev);
obj_next.html(this.plain_next);
return;
}
if (this.prevok()) {
obj_prev.html(this.link_prev);
$('#' + this.id_prev + ' a').click(function(event){
JsPrevNextPager(curr_id).clickprev();
event.preventDefault();
});
} else {
obj_prev.html(this.plain_prev);
}
if (this.nextok()) {
obj_next.html(this.link_next);
$('#' + this.id_next + ' a').click(function(event){
JsPrevNextPager(curr_id).clicknext();
event.preventDefault();
});
} else {
obj_next.html(this.plain_next);
}
};
}
使い方サンプル兼動作確認用HTML(というかPHP) :
<html>
<head>
<style type="text/css">
<!--
div.block1 {
display: none;
border: 1px solid red;
}
div.block2 {
display: none;
border: 1px solid blue;
}
.plain2 {
color: #aaa;
background-color: #333;
text-decoration: underline;
}
a.link2:link {
color: #333;
background-color: #aaa;
text-decoration: none;
}
a.link2:visited {
color: #333;
background-color: #aaa;
text-decoration: none;
}
-->
</style>
<script src="../jquery-1.2.6.min.js" type="text/javascript" ></script>
<script src="JsPrevNextPager.js" type="text/javascript" ></script>
</head>
<body>
<!-- [start] default parameter example -->
<h2>default parameter</h2>
<script type="text/javascript">
<!--
$(function(){
pager1 = new JsPrevNextPager('id1');
pager1.all = $('#page_container > div').size();
if (0 < pager1.all) {
$('#page_container>div:first').css('display', 'block');
$('#pageno_cur').text(pager1.current);
$('#pageno_all').text(pager1.all);
}
pager1.update_navilinks();
});
-->
</script>
<div id="page_navi">
page <span id="pageno_cur"></span> / all <span id="pageno_all"></span>,
<span id="page_prev"></span> /
<span id="page_next"></span>
</div>
<hr />
<div id="page_container">
<?php for ($i = 1; $i <= 10; $i++) : ?>
<div id="page_<?php echo $i; ?>" class="block1">
Page Block No <?php echo $i; ?>.
</div>
<?php endfor; ?>
</div>
<!-- [end] default parameter example -->
<!-- [start] customized parameter example -->
<h2>customized parameter</h2>
<script type="text/javascript">
<!--
$(function(){
pager2 = new JsPrevNextPager('id2');
pager2.id_pageno_cur = 'pageno_cur2';
pager2.id_eachpage = 'page_foobar_';
pager2.id_prev = 'page_prev2';
pager2.id_next = 'page_next2';
pager2.plain_next = '<span class="plain2">次のページ</span>';
pager2.plain_prev = '<span class="plain2">前のページ</span>';
pager2.link_next = '<a href="#" class="link2">次のページ</a>';
pager2.link_prev = '<a href="#" class="link2">前のページ</a>';
pager2.all = $('#page_container2 > div').size();
if (0 < pager2.all) {
$('#page_container2>div:first').css('display', 'block');
$('#pageno_cur2').text(pager2.current);
$('#pageno_all2').text(pager2.all);
}
pager2.update_navilinks();
});
-->
</script>
<div id="page_navi">
page <span id="pageno_cur2"></span> / all <span id="pageno_all2"></span>,
<span id="page_prev2"></span> /
<span id="page_next2"></span>
</div>
<hr />
<div id="page_container2">
<?php for ($i = 1; $i <= 5; $i++) : ?>
<div id="page_foobar_<?php echo $i; ?>" class="block2">
Page Block No <?php echo $i; ?>.
</div>
<?php endfor; ?>
</div>
<!-- [end] customized parameter example -->
</body>
</html>