Unformed Building

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

公開:
更新:

パーマリンク

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

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

2010年9月30日 追記:
jQueryプラグインを作成しましたので、こちらをどうぞ。

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

まず、基本となる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年8月5日)

// 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');

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