jQuery を使って blockquote の cite 属性と title 属性でリンクを生成して表示させようとしてみた

Category : HTML, jQuery

個人的に blockquote 要素はそれ単体で十分と思っているんですが、引用元がパッと見て分からないのが困り物。
ブラウザによってはプロパティで見れたりしますが、見る人に手間をかけさせることになります。
CSS の :before:after 擬似要素と content プロパティで表示させるという手もあるにはありますが、これはこれで出力されたテキストが選択できないんですね(Opera はできます)。
結局、HTML を書くときにこっちでリンクすることになるわけですが、これがまた面倒くさい。

こういうときこそ JavaScript の出番じゃないかと思って、jQuery を使って blockquote 要素の cite 属性をリンクにするスクリプトを素人ながら書いてみましたよ。
アンカーテキストは title 属性の値を利用します。

基本マークアップと出力方法

まず、基本となる blockquote のマークアップ

<blockquote cite="URI" title="引用元タイトルなど">
	<p>引用文</p>
</blockquote>

この引用文の直後にリンクを表示させたい。
あとで CSS でスタイル指定をすることも考えて、以下のようにしたいと思います。

<div class="quote">
	<blockquote cite="URI" title="引用元タイトルなど">
		<p>引用文</p>
	</blockquote>
	<a href="cite属性の値" class="cite">title属性の値</a>
</div>

引用元の文書が Web 上にあるのならこれでいいと思います。
書籍の場合はリンクするわけにもいかないので、以下のようにしたい。

<div class="quote">
	<blockquote cite="URI" title="引用元タイトルなど">
		<p>引用文</p>
	</blockquote>
	<span class="cite">title属性の値</span>
</div>

また、引用元が Web 上のテキストであろうと書籍であろうと、title 属性がない場合は cite 属性の値を代わりに表示したいと思います。

jQuery を使ったスクリプトを書いてみる

リンクを表示させたいだけなら以下ので十分だと思います。

jQuery(function ($) {
	$('blockquote').each(function () {

		// blockquoteをdivで囲む
		$(this).wrap('<div class="quote"></div>');

		// title属性とcite属性の値を変数に代入
		var title = $(this).attr('title');
		var cite = $(this).attr('cite');

		// blcokquote の直後にリンクを生成
		$(this).after('<a href="' + cite + '" class="cite">' + title + '</a>');

	});
});

しかしこれでは cite 属性があろうとなかろうとリンクを生成してしまうし、引用元が書籍の場合に困ります。
また、title 属性のみの場合にも困ったことになっちゃいます。

いろいろやっているうちに出来上がったものが以下。

jQuery(function ($) {
	$('blockquote').each(function () {

		// blockquoteをdivで囲む
		$(this).wrap('<div class="quote"></div>');

		// title属性とcite属性の値を変数に代入
		var title = $(this).attr('title');
		var cite = $(this).attr('cite');

		// cite属性の値をurlとurn:isbnに分ける
		var url = $(this).filter('[cite^=http]').attr('cite');
		var isbn = $(this).filter('[cite^=urn:isbn]').attr('cite');

		// cite属性値がurlの場合
		if (cite === url) {
			if (title != '') { // title属性が空じゃない(存在する)場合
				$(this).after('<a href="' + cite + '" class="cite">' + title + '</a>');
			} else {
				$(this).after('<a href="' + cite + '" class="cite">' + cite + '</a>');
			}
		}

		// cite属性値がurn:isbnの場合
		else if (cite === isbn) {
			if (title != '') { // title属性が空じゃない場合
				$(this).after('<span class="cite">' + title + '</span>');
			} else {
				$(this).after('<span class="cite">' + cite + '</span>');
			}
		}

		// cite属性が空、且つ、title属性が空じゃない場合
		else if ((cite === '') && (title != '')) {
			$(this).after('<span class="cite">' + title + '</span>');
		}
		// cite属性とtitle属性のどちらも存在しない場合は何もしない
	});
});

それにしても、こんなに条件分岐まみれでいいんだろうか。
もっとスマートなコードに出来る気がする。
でも今の実力じゃこれが限界。
もっとできるようになったら直すかもしれない。

チェンジログ

2010-08-05
// cite属性の値をurlとurn:isbnに分ける
var url = $('blockquote[cite^=http]').attr('cite');
var isbn = $('blockquote[cite^=urn:isbn]').attr('cite');

この部分を

// cite属性の値をurlとurn:isbnに分ける
var url = $(this).filter('[cite^=http]').attr('cite');
var isbn = $(this).filter('[cite^=urn:isbn]').attr('cite');

に修正。
上田さん ご指摘ありがとうございました。

Trackbacks & Pingbacks

Leave a Reply