【Javascript】FC2のプラグインを改造してみよー
2014.08.04 21:36 | コメント(0) | 技術
この記事は最終更新日から1年以上が経過しています。
→更新記事を書きました。
ちまちまと時間を見つけては改造してたプラグインがひと段落しましたw
さっちんですねー。
今回は、左側に出してる基本プラグイン「月別アーカイブ」をいじくってみました。
before
after
長い・・・。
これがこの先ずんずん長くなっていくと思うとちょっとムズッとしたので、
少しスリムにしてみました。
今回はDOM操作を駆使してJavascriptで実装してみましたよー♪
現行コードの確認
まず、今の状態のソースコードを確認します。
<ul id="archive">
<!--archive-->
<li &align>
<a href="<%archive_link>" title="<%archive_year>/<%archive_month>">
<%archive_year>/<%archive_month> (<%archive_count>)</a>
</li>
<!--/archive-->
</ul>
わー。しんぷる。
こっからわかることを簡単にまとめると、
- リスト形式で出力
- なんか対のコメントアウトがある
- リンクと思しきものが動的に生成されてる
まーHTMLのタグの形式は割とどーでもいいかな。
それよりも一番気になったのがこの2つ。
<!--archive-->
~略~
<!--/archive-->
と、
<%~>
答えはこちら
ふむふむ、この記述はアーカイブ(月別の記事数)の一覧を表示するらしい。
<%~>
は、月別の変数みたいだねー。
詳しい使い方は、さっきのヘルプページを見てくださいw
んし、じゃー作り変えていこうかな!
完成図を考える
作る前に、どんなものが作りたいか考えてみます。
ざっくり方向性を決めないと作ってる最中に「あれ?何作ってんだっけ?」ってなりますからねw
私の今回の一番の目標はスリム化なので、まず毎月1行ずつ増えていく現状のデザインは無いです。
で、今回のざっくりプランはこんな感じ。
- 年別の中カテゴリを設置する
- 月は2ケタ表示(01~12)で表示する
- 月は半年を1段として、2段表示とする
- アーカイブ表示が歯抜けにならないように、記事を書いていない月についても表示する
- 年間の記事数を取得し、表示する
これだけできればとりあえず満足かなー。
tableタグを使用した理由はCSSの調整が楽だからw
まあ月別の表だから間違いではないでしょー。
組み込む
さて、実際に組んでいきます。、
実際に作成したソースコードにコメントを入れてみました。
<table id="archive"></table>
<script type="text/javascript">
/* 今回のスクリプトで必要な変数をセット。 */
var parent = $('table#archive'); /* 入れ物の指定。 */
var prev_month = 12; /* 月別セル作成時の比較用変数(後述)。 */
<!--archive--> /* 月別アーカイブループ開始 */
/* 年・月・月別記事数・月別ページへのリンクを変数にセット。 */
var year = <%archive_year>;
var month = parseInt('<%archive_month>');
var count = <%archive_count>;
var url = '<%archive_link>';
/* 現在ループ中の年セルがあるかどうか確認。
→なければ作る。 */
var year_id = 'archive_' + year;
var year_cell = $('#' + year_id);
if ( year_cell.length == 0 ) {
parent.append(
$('<tr>')
.attr('id', year_id)
.append(
$('<th>')
.attr('colspan', 6)
.append(year + '年')
)
);
}
/* 現在ループ中の月とprev_month変数を比較。
* prev_monthの値の方が大きければ、ループ中の月まで
* 空の月セルを作成する。 */
if ( month < prev_month ) {
while ( month < prev_month ) {
if ( prev_month > 6 ) {
var target_id = year + '_u';
} else {
var target_id = year + '_l';
}
/* 現在ループ中の月セルがあるかどうか確認。
* →なければ作る。 */
var target = $('#' + target_id);
if ( target.length == 0 ) {
parent.append(
$('<tr>')
.attr('id', target_id)
);
var target = $('#' + target_id);
}
/* 月セルの中身を作成。
* ただし、空の月セルのため、リンクは設定しない。 */
target.append(
$('<td>').addClass('inactive').append(
$('<span>')
.attr('title', year + '年' + prev_month + '月(0)')
.append( ('0' + prev_month).slice(-2) )
)
);
/* prev_month変数の値を1減少させ、while文の先頭に戻る。 */
prev_month -= 1;
}
} else {
/* prev_monthより現在ループ中の月の値が大きい場合の処理。
* 処理内容は上記と同様。 */
if ( month != prev_month ) {
while ( 1 <= prev_month ) {
if ( prev_month > 6 ) {
var target_id = ( year + 1 ) + '_u';
} else {
var target_id = ( year + 1 ) + '_l';
}
var target = $('#' + target_id);
if ( target.length == 0 ) {
parent.append(
$('<tr>')
.attr('id', target_id)
);
var target = $('#' + target_id);
}
target.append(
$('<td>').addClass('inactive').append(
$('<span>')
.attr('title', ( year + 1 ) + '年' + prev_month + '月(0)')
.append( ('0' + prev_month).slice(-2) )
)
);
prev_month -= 1;
}
prev_month = 12;
if ( month < prev_month ) {
while ( month < prev_month ) {
if ( prev_month > 6 ) {
var target_id = year + '_u';
} else {
var target_id = year + '_l';
}
var target = $('#' + target_id);
if ( target.length == 0 ) {
parent.append(
$('<tr>')
.attr('id', target_id)
);
var target = $('#' + target_id);
}
target.append(
$('<td>').addClass('inactive').append(
$('<span>')
.attr('title', year + '年' + prev_month + '月(0)')
.append( ('0' + prev_month).slice(-2) )
)
);
prev_month -= 1;
}
}
}
}
/* 現在ループ中の月セルを作成。 */
if ( month > 6 ) {
var target_id = year + '_u';
} else {
var target_id = year + '_l';
}
var target = $('#' + target_id);
if ( target.length == 0 ) {
parent.append(
$('<tr>')
.attr('id', target_id)
);
var target = $('#' + target_id);
}
target.append(
$('<td>').append(
$('<a>')
.attr('href', url)
.attr('title', year + '年' + month + '月(' + count + ')')
.append( ('0' + month).slice(-2) )
)
);
prev_month -= 1;
<!--/archive--> /* アーカイブループ終了 */
/* 年の途中(たとえば2011/11など)からブログを開設した場合、
* その年の過去の月について、空のセルを作成する。 */
/* 一番古いアーカイブの年セルを取得。 */
var last_child = $('table#archive tr:last-child');
/* 年を取得。 */
var target_year = last_child.attr('id').replace(/(_u|_l)/, '');
/* 一番古い年の内、作成済みの月セル数をセット。 */
var fill_length = $('#' + target_year + '_u td').length
+ $('#' + target_year + '_l td').length;
/* 未作成の月セルの数をセット。 */
var remain_month = 12 - fill_length;
while ( 0 < remain_month ) {
if ( remain_month > 6 ) {
var target_id = target_year + '_u';
} else {
var target_id = target_year + '_l';
}
var target = $('#' + target_id);
if ( target.length == 0 ) {
parent.append(
$('<tr>')
.attr('id', target_id)
);
var target = $('#' + target_id);
}
target.append(
$('<td>').addClass('inactive').append(
$('<span>')
.attr('title', target_year + '年' + remain_month + '月(0)')
.append( ('0' + remain_month).slice(-2) )
)
);
remain_month -= 1;
}
/* 年セルに年間の作成記事数を追加する。 */
var archives = $('table#archive tr[id*="archive_"]');
$.each(archives, function(idx, elem) {
var year = elem.getAttribute('id').replace('archive_', '');
var count = 0;
$.each(['_u', '_l'], function(i, str) {
var parent = $('#' + year + str);
var children = parent.find('td');
$.each(children, function(j, child) {
var m_count = parseInt(child.children[0].getAttribute('title').slice(-2, -1));
count = count + m_count;
})
})
elem.children[0].innerHTML += '(' + count + ')';
})
</script>
ソースコードを見るソースコードを隠す
はい。このとおりです(大雑把)
まあちょっと読める人が見たら、すぐわかると思うんですが、
無駄な記述が多い
プログラムする際によく言われることですが、「DRY(Don't Read Yourself)に作れ!」
これは同じコードをうんちゃらうんちゃら何箇所にも書くと冗長的になって可読性が下がるし、変更を加えるときにたくさんの箇所を触らないといけなくなって保守性が下がる。
つまり、どうするかというと、同じコードはまとめてしまいましょうということですね。
Javascriptの場合、function(){}で関数を定義してやって、必要な部分で呼び出すとすごく楽ですよ。
じゃあなんでオマエはやってないの?
答えは簡単。
FC2が関数を作らせてくれないから(´;ω;`)
なんでなんだよーう・・・。
なんで直書きしか許してくれないんだよーう・・・。
XSS(Cross Site Scripting)エラーが出てたけど、直書きスクリプトが動く時点で同じじゃないかー(´;ω;`)
ココなんでこんなことしてんの?
とか、これはどういう処理なの?
とかあればご意見くださいね(*´∀`)
ちなみに、私が作成したコレは自由に使ってくださって構いません。
こんなんを使いたがる人がいるとは考えにくいけど・・・w
コメントアウトを取ったコードを公開しておきますねー。
(長いからまた畳んでおきます。)
<table id="archive"></table>
<script type="text/javascript">
var parent = $('table#archive');
var prev_month = 12;
<!--archive-->
var year = <%archive_year>;
var month = parseInt('<%archive_month>');
var count = <%archive_count>;
var url = '<%archive_link>';
var year_id = 'archive_' + year;
var year_cell = $('#' + year_id);
if ( year_cell.length == 0 ) {
parent.append(
$('<tr>')
.attr('id', year_id)
.append(
$('<th>')
.attr('colspan', 6)
.append(year + '年')
)
);
}
if ( month < prev_month ) {
while ( month < prev_month ) {
if ( prev_month > 6 ) {
var target_id = year + '_u';
} else {
var target_id = year + '_l';
}
var target = $('#' + target_id);
if ( target.length == 0 ) {
parent.append(
$('<tr>')
.attr('id', target_id)
);
var target = $('#' + target_id);
}
target.append(
$('<td>').addClass('inactive').append(
$('<span>')
.attr('title', year + '年' + prev_month + '月(0)')
.append( ('0' + prev_month).slice(-2) )
)
);
prev_month -= 1;
}
} else {
if ( month != prev_month ) {
while ( 1 <= prev_month ) {
if ( prev_month > 6 ) {
var target_id = ( year + 1 ) + '_u';
} else {
var target_id = ( year + 1 ) + '_l';
}
var target = $('#' + target_id);
if ( target.length == 0 ) {
parent.append(
$('<tr>')
.attr('id', target_id)
);
var target = $('#' + target_id);
}
target.append(
$('<td>').addClass('inactive').append(
$('<span>')
.attr('title', ( year + 1 ) + '年' + prev_month + '月(0)')
.append( ('0' + prev_month).slice(-2) )
)
);
prev_month -= 1;
}
prev_month = 12;
if ( month < prev_month ) {
while ( month < prev_month ) {
if ( prev_month > 6 ) {
var target_id = year + '_u';
} else {
var target_id = year + '_l';
}
var target = $('#' + target_id);
if ( target.length == 0 ) {
parent.append(
$('<tr>')
.attr('id', target_id)
);
var target = $('#' + target_id);
}
target.append(
$('<td>').addClass('inactive').append(
$('<span>')
.attr('title', year + '年' + prev_month + '月(0)')
.append( ('0' + prev_month).slice(-2) )
)
);
prev_month -= 1;
}
}
}
}
if ( month > 6 ) {
var target_id = year + '_u';
} else {
var target_id = year + '_l';
}
var target = $('#' + target_id);
if ( target.length == 0 ) {
parent.append(
$('<tr>')
.attr('id', target_id)
);
var target = $('#' + target_id);
}
target.append(
$('<td>').append(
$('<a>')
.attr('href', url)
.attr('title', year + '年' + month + '月(' + count + ')')
.append( ('0' + month).slice(-2) )
)
);
prev_month -= 1;
<!--/archive-->
var last_child = $('table#archive tr:last-child');
var target_year = last_child.attr('id').replace(/(_u|_l)/, '');
var fill_length = $('#' + target_year + '_u td').length
+ $('#' + target_year + '_l td').length;
var remain_month = 12 - fill_length;
while ( 0 < remain_month ) {
if ( remain_month > 6 ) {
var target_id = target_year + '_u';
} else {
var target_id = target_year + '_l';
}
var target = $('#' + target_id);
if ( target.length == 0 ) {
parent.append(
$('<tr>')
.attr('id', target_id)
);
var target = $('#' + target_id);
}
target.append(
$('<td>').addClass('inactive').append(
$('<span>')
.attr('title', target_year + '年' + remain_month + '月(0)')
.append( ('0' + remain_month).slice(-2) )
)
);
remain_month -= 1;
}
var archives = $('table#archive tr[id*="archive_"]');
$.each(archives, function(idx, elem) {
var year = elem.getAttribute('id').replace('archive_', '');
var count = 0;
$.each(['_u', '_l'], function(i, str) {
var parent = $('#' + year + str);
var children = parent.find('td');
$.each(children, function(j, child) {
var m_count = parseInt(child.children[0].getAttribute('title').slice(-2, -1));
count = count + m_count;
})
})
elem.children[0].innerHTML += '(' + count + ')';
})
</script>
ソースコードを見るソースコードを隠す
ちなみに当ててるCSSはこちらー。
これもご自由に変更くださーい。
/* Archives Plug-in */
table#archive {
padding: auto 2px;
width: 90%;
margin: auto;
text-align: center;
}
table#archive th {
padding-top: 10px;
font-size: 110%;
}
table#archive td a {
font-weight: bold;
color: #9f7349;
}
table#archive td.inactive {
color: #828282;
}
と、まあ今回は大半の方には興味のないJavascriptのお話でしたー。
DOM操作楽しい(・∀・)
まだコメントがありません...(´・ω・`)