リンクで_blankを使わず別窓が開く画像を表示させる方法

ウェブページでリンクをクリックして、新しいウィンドウ表示するには、普通target="_blank"を使います。このかわりにJavaScriptを使って外部リンクなら自動的に別窓が開く画像を表示させる方法を試してみました。

リンクを新しいウィンドウに表示させるかどうかの問題

サーバーの写真

リンクを新しいウィンドウに表示したいと思ったら、リンクを右クリックしてメニューから選ぶか、SHIFTかCTRLキーを押しながらリンクをクリックするのが普通です。

ウェブページ楽天 でリンクをクリックして、新しいウィンドウ表示するには、普通target="_blank"を使います。しかし、この書き方はXHTML (1.0Strictや1.1)には準拠していません。

これは、新しいウィンドウを開くかどうかはユーザーが決めるべき問題で、ウェブページ側では決めないという考え方からきています。

でも、全ユーザーが新しいウィンドウで開くやり方を知っているかというと疑問です。やはり外部リンクは新しい窓で開きたいものです。そうしないとまた元のページに戻ってくるのが大変ですし、もう戻ってきてくれないかも知れません。

target="_blank"を使うと、HTMLの文法チェッカーで検査すると、間違っていると警告が出ることがあります。これを回避するにはJavaScriptを使う方法があります。これは「新ウィンドウに表示1」として以前に別の記事を書いています。

外部リンクなら自動的に別窓が開く画像をテキストリンクの横に表示させる方法

上記の方法でも一応の要求は満たされますが、 更に良い方法がありましたので試してみました。それは、外部リンクなら自動的に別窓が開く画像をテキストリンクの横に表示させる方法です。

この方法では、でき上がったページに何も手を加えることなく、このスクリプトを適用するだけで目的を達することができるというメリットがあります。また、別窓で開くかどうかを自分で選べるというメリットもあります。

このスクリプトは外部jsファイルにしています。このスクリプトの使い方はスクリプト中のコメントを参照してください。

また、後述のようにaddEventという関数機能を使ってこれを呼び出しています。

実際のスクリプト

//New Window JavaScript
//openType : [1:target="_blank"][2:window.open(this.href)]
//checkArea : 適用するエリアのid(ページ全体なら [checkArea = ''])
//exclusionStr : 除外する文字列(リンクすべてに適用するなら [exclusionStr = new Array()])
//inclusionClassName : 除外文字列を含んでいても<a class="nw">テキスト</a>と書かれていれば適用する。
//anchorObject : 表示するオブジェクト(テキストの場合[var anchorObject = 'テキスト';])
var openType = 1;
var checkArea = '';
var exclusionStr = new Array('http://hogehoge.net','hoge.jp');
var inclusionClassName = 'nw'; 
var anchorObject = '<img src="/img/new_win.gif" alt="nw" title="Open new window" style="margin:0" />';
var isIE = (document.documentElement.getAttribute("style") == document.documentElement.style);
function newWin(){
  if(checkArea == ''){
    var anchors = document.getElementsByTagName('a');
  }else{
    var anchors = document.getElementById(checkArea).getElementsByTagName('a');
  }
  for(i = 0; i < anchors.length; i++){
    var exNum = 0;
    var anchor = anchors[i];
    var aInner = anchor.innerHTML;
    var ahref = anchor.href;
    if(aInner.indexOf('<img') == -1){
      for(j = 0; j < exclusionStr.length; j++){
        eAnchor = exclusionStr[j];
        if((ahref.indexOf(eAnchor) == -1 || anchor.className == inclusionClassName) & anchor.href != ''){
          exNum++;
        }
      }
      if(exNum == exclusionStr.length){
        var winAnchor = document.createElement('a');
        winAnchor.innerHTML = anchorObject;
        winAnchor.href = anchor.href;
        winAnchor.className = 'newWin';
        if(openType == 1){
          winAnchor.setAttribute('target','_blank');
        }else if(openType == 2){
          if(isIE) {
            winAnchor.setAttribute('onclick',new Function('window.open(this.href,\'\',\'status=yes,scrollbars=yes,directories=yes,menubar=yes,resizable=yes,toolbar=yes\'); return false;'));
          }else{
            winAnchor.setAttribute('onclick','window.open(this.href,\'\',\'status=yes,scrollbars=yes,directories=yes,menubar=yes,resizable=yes,toolbar=yes\'); return false;');
          }
        }
        anchor.parentNode.insertBefore(winAnchor,anchor);
        anchor.parentNode.replaceChild(winAnchor,anchor);
        winAnchor.parentNode.insertBefore(anchor,winAnchor);
        var i = i + 1;
      }
    }
  }
}
addEvent(window,"load",newWin);

このコードを例えばexternal.jsという名前でドメインルート等に保存し、アップロードします。これを呼び出すには、HTMLヘッダー部で次のように記述します。

<script type="text/javascript" src="http://hogehoge.jp/external.js"></script>

複数のJavascriptイベントを動作させる方法

複数のJavaScriptライブラリを利用している場合、正常に動作しなかったり、どちらか一方しか動作しなかったりすることがあります。

これは、 JavaScriptのonloadは、ブラウザがすべてを読み込んでから実行するので、最後に記述した命令しか実行しないからです。

私は、他でも既に、JavaScriptのonloadを使っていましたので、今回もこの機能を使いました。

// addEvent
function addEvent(elm,listener,fn){
  try{
    elm.addEventListener(listener,fn,false);
  }catch(e){
    elm.attachEvent("on"+listener,fn);
  }
}

これは、addEventListenerという機能を利用して、ひとつのイベントに対して命令を追加していく関数になります。

IEではaddEventListenerが利用できないので、attachEventという関数で代用しています。