読者です 読者をやめる 読者になる 読者になる

rakugakibox.net

技術ノート。兼JS/CSS実験場。 ♡:Java, Spring, AWS.

外部リンクを別窓で開くJavaScript, 動的追加されるリンクにも対応させてみた (jQuery使用)

JavaScript Programming

外部リンクは軒並み target="_blank" にして別窓で開きたいことがある。

そんなとき、HTMLが修正出来ないページ(このはてなブログも)では
JavaScriptで対応することになるのだけど、
よくある方法では不十分だったので自前で実装してみた。

よくある方法

よくあるのはこんな感じのコード。
DOM Readyをトリガーに、対象の要素に対して target="_blank" をセットしていく。
属性セレクタで自サイトのホスト名を含まないリンクを対象にしてる。

$(function() {
  $("a[href^=http]:not([href*='" + location.hostname + "'])"
    ).attr("target", "_blank");
});

参考サイト

それでは不十分なこと

Ajax等で、DOM Readyより後に追加されたリンクに対応出来ない。
はてなブログだと、はてなスター, コメントあたりがそんな動きをしてた。

DOM Readyより後に追加されたリンクにも対応してみた

こんなコードを書いたらそれっぽく動いた。

リンククリックをトリガーに、windowまで伝搬されたイベントを拾って対応してる。
a要素を検索しない分、大きなページでは表示も高速化するかもしれない(未確認)。

$(window).click(function(event) {
  var target = $(event.target);
  if (!target.is("a")) {
    target = target.parents("a").first();
  }
  target.filter(
      "[href^=http]:not([href*='" + location.hostname + "'])"
    ).attr("target", "_blank");
});

この方法の残念なこと

CSSで外部リンクの見た目を変えたいって場合には向かない。
例えば別窓を開きますよ的なアイコンを横に置いたりとか。

属性セレクタ [target="_blank"] { ... } を使っても、
addClass("ext_link") してクラスセレクタ .ext_link { ... } を使っても、
有効になるのがclickタイミングなので意味がない。

もしDOM Ready後の追加要素にはCSS適用しなくて良ければ、
前記したよくある方法と併用するといいかもしれない。

関連記事