target="_blank" をどうするか

ここ数年、自分でサイトを作る時はHTML4.01もしくはXHTML1.0のStrictで通してきました。当然、target属性はサポートしていないので「target="_blank"」の指定はできません。「onclick="window.open(this.href,'');return false"」と記述しておけば実際のところ問題ないので、それでよしとしてきました。厳密にはonkeypress属性にも同様の指定が必要らしいのですが、とりあえず実用上の問題はないということで放置していました。JavascriptがOFFになっている環境では別ウィンドウになりませんが、そういうユーザーは別ウィンドウで開きたければ自分で開くだろうということでOKとします。

個人的にはonclickの記述をそんなに面倒だと思わなかったのですが、チーム体制で仕事をするに当たってはやはり若干の不安要素になります。

function wopen(obj) {
    window.open(obj.href,'');
    return false;
}

といった関数を定義した上で「onclick="return wopen(this)"」と書くこともできますが、「target="_blank"」に比べて複雑な感は否めません。

window.onload = function() {
    var nodes = document.getElementsByTagName('a');
    for (var i=0; i<nodes.length; i++) {
        if (nodes[i].rel == 'external') {
            nodes[i].onclick = nodes[i].onkeypress = function() {
                window.open(this.href,'');
                return false;
            }
        }
    }
}

てな具合にしてやれば、<a href="〜" rel="external">なリンクが全て別ウィンドウで開くようになります。onkeypress属性もちゃんと設定させているし、HTMLの記述も簡潔になります。これを外部ファイルにしておいて、呼び出してやればかなりすっきりします。

ただし、window.onloadで他のことをしたい場合にはこれではまかなえません。となると、やはりprototype.jsを利用して、

Event.observe(window, 'load', function() {
    〜 ここの処理は同じように 〜
});

このように定義するのがスマートでしょう。こうしてやれば、Strictなコードで簡潔に記述できて、望む挙動も実現できます。

しかしながら、ここで「そこまでする問題か?」という疑問が頭をもたげてきます。確かにこのようなコーディングは

  • Strictなコードが書ける
  • XHTML1.1への移行も問題なし
  • 他の処理(別ウィンドウで開くリンクにアイコンを付けるなど)を埋め込める

といった利点はありますが、「別にいいんじゃない?」と言ってしまえばそれまでです。逆に、

  • prototype.jsを読み込む必要がある
  • target="_blank"しか知らない人間が理解しづらい

というデメリットが無視できないケースも想定できます。なんだかんだでprototype.jsも結構な分量があるので、サーバへのトラフィックという面ではあまり嬉しくない存在です。

確かにStrictで書けば、ロジックとデザインの分離は結構なレベルで強制されますし、使用できる属性も限られてくるので安定したソースになります。とはいえ、間違ったStrictでもブラウザではエラーにならないため、結局はコードの質は書く人間次第です。そうなると、Transitionalで「Strictでも通るコード+target="_blank"だけ解禁」というのが現場レベルの判断としては妥当な線なのかなぁ…という気がしてきてます。

また、ブログやCMSでのテンプレートとして考えると、ユーザーがHTMLを書き込む場合にStrictを強制するのはやはり難しいでしょう。HTMLを書かせないなら問題ないのですが、それを前提としてコーディングするのも融通が利きませんね。