【jQuery】ページ内の全リンクに共通クラスを自動付与する完全ガイド|外部リンク・条件付き・target=”_blank”・セキュリティまで

【jQuery】ページ内の全てのリンクに共通クラスを自動付与する方法 jQuery

ページ内のすべての外部リンクにアイコンを付けたり、特定の条件に合うリンクだけ装飾を変えたりする処理は、jQueryで簡単に一括対応できます。この記事では全リンクへのクラス付与・外部リンクの自動検出・target=”_blank”のセキュリティ対策・noopenerの自動付加まで解説します。

この記事でわかること

  • ページ内の全リンクに共通クラスを付与する
  • 外部リンクを自動検出してアイコンクラスを追加する
  • target=”_blank” を自動設定してrel=”noopener noreferrer”を付加する
  • PDFリンク・ダウンロードリンクに自動でクラスを付ける
  • WordPressの投稿内リンクだけに限定する
スポンサーリンク

全リンクにクラスを付与する基本

$(function () {
  // ページ内の全 <a> 要素にクラスを追加
  $('a').addClass('link-styled');

  // hrefがあるリンクのみ(アンカー <a name='top'> を除く)
  $('a[href]').addClass('link-styled');

  // 特定のコンテナ内のリンクのみ
  $('.entry-content a[href]').addClass('link-styled');
});

外部リンクを自動検出してクラス・アイコンを追加する

$(function () {
  var currentHost = location.hostname; // 例: 'codingls.com'

  $('a[href]').each(function () {
    var href = $(this).attr('href');

    // プロトコル相対URL・http/httpsリンクで別ドメインのものを外部リンクとして判定
    var isExternal = /^https?:\/\//i.test(href) &&
                     href.indexOf(currentHost) === -1;

    if (isExternal) {
      $(this).addClass('external-link'); // 外部リンクのクラス
    }
  });
});
相対URL・ルート相対URLは自動的に内部リンクと判定される
/about/../page.html などの相対URLには http:// が含まれないため、上記の正規表現では外部リンクとして判定されません。サイト内リンクには基本的に相対URLを使いましょう。

外部リンクにtarget=”_blank”とnoopenerを自動付加する

外部リンクを新しいタブで開く場合、rel="noopener noreferrer" の付加がセキュリティ上必要です。

$(function () {
  var currentHost = location.hostname;

  $('a[href]').each(function () {
    var href = $(this).attr('href');
    var isExternal = /^https?:\/\//i.test(href) &&
                     href.indexOf(currentHost) === -1;

    if (isExternal) {
      $(this)
        .attr('target', '_blank')                    // 新しいタブで開く
        .attr('rel', 'noopener noreferrer')          // セキュリティ対策
        .addClass('external-link');
    }
  });
});
rel=”noopener noreferrer” は必須
target="_blank" だけでは、リンク先ページが window.opener を通じて元のページを操作できてしまいます(タブナビゲーション攻撃)。rel="noopener" でこの脆弱性を防ぎます。noreferrer を追加すると Referer ヘッダーも送信されなくなります。

PDFやダウンロードリンクに自動でクラスを付ける

$(function () {
  // PDFリンク
  $('a[href$=".pdf"]').addClass('link-pdf').attr('target', '_blank');

  // ダウンロードリンク(download属性がある)
  $('a[download]').addClass('link-download');

  // 複数の拡張子
  $('a[href]').filter(function () {
    return /\.(pdf|doc|docx|xls|xlsx|zip)$/i.test($(this).attr('href'));
  }).addClass('link-file');
});

WordPressの投稿内リンクに限定する

$(function () {
  var currentHost = location.hostname;

  // .entry-content(投稿本文)内のリンクのみ対象
  $('.entry-content a[href]').each(function () {
    var href = $(this).attr('href');
    var isExternal = /^https?:\/\//i.test(href) &&
                     href.indexOf(currentHost) === -1;

    if (isExternal) {
      $(this)
        .attr({ target: '_blank', rel: 'noopener noreferrer' })
        .addClass('external-link');
    }
  });
});
WordPressではfunctions.phpでも同様の処理が可能
WordPressのコンテンツフィルタ(the_contentフィルター)やTinyMCEの設定でサーバーサイドから外部リンクの属性を付加することもできます。JavaScriptよりPHPで処理する方がSEO観点では有利です。

まとめ

jQueryでリンクに自動クラス付与する際のポイントをまとめます。

  • 全リンク: $("a[href]").addClass("cls")
  • 外部リンク検出: location.hostname と比較
  • target=”_blank”: 必ず rel="noopener noreferrer" をセット
  • ファイルリンク: [href$=".pdf"] または正規表現で拡張子フィルタ

関連記事: URLに特定の文字列が含まれているか判定する方法 / imgタグのalt属性を取得・設定する完全ガイド

よくある質問(FAQ)

QAjaxで追加したリンクにも自動でクラスを付けたいです。
A初期実行の処理を関数化して、Ajax完了後のコールバックで再呼び出しします。または MutationObserver でDOM変化を監視して、追加されたリンクを検出する実装も可能です。イベントデリゲーションはクラス付与には使えないため(クリックではなく属性操作のため)、この方法を使ってください。
Q特定のリンクにはクラスを付与したくないです。
A.not(".no-auto-class") で除外できます:$("a[href]").not(".no-auto-class, .btn").addClass("link-styled")または data-no-external のようなデータ属性で除外フラグを管理する方法もあります。
Qanchorリンク(#section など)は除外したいです。
A$("a[href]").not("[href^="#"]") で # 始まりのリンクを除外できます。または .filter(function() { return !$(this).attr("href").startsWith("#"); }) でも同様です。
Qメール(mailto:)や電話(tel:)リンクも外部リンク扱いにしたくないです。
Ahref が mailto:tel: から始まるリンクを除外します:$("a[href]").not("[href^="mailto:"], [href^="tel:"]")または条件チェック内で href.startsWith("mailto:") || href.startsWith("tel:") の場合はスキップします。
Q外部リンクのアイコンをCSSで表示したいです。
AjQueryで追加したクラスに対してCSSの ::after 疑似要素でアイコンを表示できます:.external-link::after { content: "↗"; margin-left: 4px; font-size: 0.8em; }Font Awesomeやカスタムアイコンフォントを使う場合は content にUnicode文字を指定します。