2006年3月15日水曜日

_blankを使わないで別ウィンドウを開くにはrel="external"を使うのが美しいと思う。

はてなブックマークをみていたら、気になるエントリーを発見。


[戯] target="_blank" を使わないで新しいウィンドウでリンクを開く方法


target="_blank"という書き方がXHTML 1.1 や XHTML Basicに準拠していないので、これらに準拠するようにしつつ、別ウィンドウで開くにはどうすればよいかという話です。

別ウィンドウで開くにはJavaScriptを使えってのが推奨される方法なんですが、onclickを使って定義するのはめんどうということで、この記事では、aタグにclass="popup"という属性を与えておけば、JavaScriptで別ウィンドウを開くということをしています。

この件については友人のHTML、CSSマスターなkawachi君と話したことがあって、そのときは、下のエントリで紹介されているrel="external"という方法を使うのがいいんじゃないかという結論に達しました。


Opening a link in a new window - the valid way


僕は上のエントリを参考に以下のようなjsファイルを用意して使っています。


>

//external.js
function externalLinks() {
if (!document.getElementsByTagName) return;
var anchors = document.getElementsByTagName("a");
for (var i=0; i<anchors.length; i++) {
var anchor = anchors[i];
if (anchor.getAttribute("href") &&
anchor.getAttribute("rel") == "external")
anchor.target = "_blank";
}
}

Event.observe(window,'load', externalLinks, false);

<


使い方は簡単でこのjsファイルをインクルードするだけです。


>


<script type="text/javascript" src="/path/to/prototype.js"></script<
<script type="text/javascript" src="/path/to/external.js"></script>

<


load時にこのファンクションを実行するためにprototype.jsのEvent.observeを使っているため、
prototype.jsもインクルードしています。ここはwindow.onload=externalLinks;に書き換えれば、
prototype.jsは必要ありません。
このファイルをインクルードすると、rel="external"と指定したaタグをクリックすると別ウィンドウで開くようになります。


>


<a rel="external" href="http://www.google.com/">別ウィンドウで開きます。</a>

<


rel="external"というこのリンク先は外部のサイトだよという関連性を示す記述に対して、JavaScriptで別ウィンドウで開くんだよと定義してあげるというアプローチが美しいなと思っています。




15 件のコメント:

  1. htmlにはそれほど詳しくないので的外れな指摘かもしれませんが、
    anchor.target = "_blank";
    として別ウィンドウを開くように指定してるので、
    内部的に展開されるDOMツリーはXHTML 1.1 や XHTML Basicに準拠していないんじゃないでしょうか??
    XHTML 1.1 や XHTML Basicに準拠というのは静的なhtmlファイルがそう書かれていればOKということなのでしょうか?

    返信削除
  2. rel="external" で要素を拾いつつ、最初のネタ元のように href 属性を window.open するのがいいんではないかと思いますが、いかがでしょう。

    返信削除
  3. >Yuanyingさん
    たしかにonload時にtarget属性をセットしているので、できたDOMツリーはXHTML 1.1 や XHTML Basicに準拠していないような気がしてきました。
    >よしださん
    その方法がよさそうですね。

    返信削除
  4. で、実装非準拠のマークアップを濫造すると、
    なにが楽しいのでしょう。
    ばかばかしいと思うんだけど。

    返信削除
  5. rel="external"って準拠した書き方だと思っていましたが、もしかして非準拠??ちょっと調べたら、HTML4.0だとrel属性に指定できる値って決められてるんですね。根本からして間違い??
    それと別ウィンドウで開くためにrel="external"と使うというのは順序が逆で間違いだなと思いました。そのリンクが外部へのリンクであるという関係性を示すためにrel="external"という表現を使っているドキュメントがまず先にあって、その関係性を持ったリンクは別ウィンドウで開いてほしいからJavaScriptで後から挙動を設定するというのが正しい順番だなと思いました。

    返信削除
  6. 実情はともかく、rel属性に(X)HTML仕様で定められていないリンクタイプを記述するときは、プロファイルをhead要素で指定することになっています。
    from http://www.kanzaki.com/memo/2005/01/21-1
    らしいです。

    返信削除
  7. Yuanyingさん、情報ありがとうございます。
    プロファイルをhead要素で指定するという方法、知りませんでした。
    rel="nofollow"ってのもプロファイルを指定しないと厳密には、間違いなんですね。勉強になりました。

    返信削除
  8. コメントに静的なhtmlファイルが準拠していれば良いのかという指摘がありますが、文法に準拠したHTMLを書きあくまでDOMを使ってUAの読み込み時に汚すことと、端から汚れたHTMLを書くこととは同価ではないはずなので、僕は「相応の理由があれば」OKだと思います。
    例えば少し前に話題になったnifty cornerを例にすると、border-radiusプロパティが実装されるまでの過渡的な手段として用いるという分には一理あります。
    今回の_blankにしてもDOMで追加するほうがあとで簡単にウインドウ開くのをやめられるというメリットがあることも確かなわけで、その辺は最終的にHTMLが汚れることとのバランスをみて採用すれば別に良いのではないかと思います。
    ただリンク先の記事の場合、class名にpopupという名前を付けており、そんな一部のUAの機能に依存したクラス名を付けちゃうんだったら意味ないじゃんとは思いますが。。
    それと、ちょっと話が逸れますが、新規ウインドウで開く場合には、「新規ウインドウで開きます」と書いちゃうとか、それが冗長ならそれっぽいアイコンを添えてみるとか、技術面よりもユーザーの利便性に目を向けたほうが良いというか、サービスを考える上では面白いのではないかとか、そういう風なこと考えたりしました。あとそもそもtarget属性が廃止に至る経緯も顧ないと小手先になっちゃうかもな、とか、反省しました。

    返信削除
  9. 追加で補足です。
    今回の場合、XHTML1.0 Transitionalを採用した上で、DOMを使いtarget属性を追加するのが良いのではないかと思います。rel="external"でも良いですし、クラス名を用いるならclass="externalLink"とか、そもそもポップアップという概念を持たない環境下でも妥当な名前が良いと思います。

    返信削除
  10. はじめまして、horiuchi様。
    ふるぱ-しゃる管理人、秋月らせんと申します。
    aタグでrel="external、は目から鱗でした。
    拙サイトでの長らくの悩みに巧妙が見えました。
    html内で明示的に_blankと書いてしまうのは
    strictうんぬんを抜きにして好ましくないと思っていましたが
    さりとて、別窓表示したほうが管理人としても
    おそらく閲覧者さまの視点からしても
    良いのじゃないか、と思う事があったのも事実です。
    今回ご紹介いただいた対応方法は、
    「W3C向けの小手先の逃げ」ではなくて、美しい手法だと思います。
    理由はソース中に明示的に外部リンクだと示している事、
    アレコレ直接aタグ中にjavaのイベントを書かなくて済むのが素晴らしいです。
    外部ファイルに動作を書き出しているので、
    今後、aタグクリック時の仕様変更を行いたい!と思った時に
    容易に実現出来る(しかもhtmlソースのリビルドは不要)も素晴らしいです。
    スクリプトを利用させていただいた事のご報告と
    感謝を述べさせていただきます。
    ありがとうございました。

    返信削除
  11. 教えてください2007年11月17日 23:46

    すみません教えてください
    リンク先をtarget_blankにしたくなくてこちらの
    スクリプト使用させていただきましたが
    ジャバのスクリプトが無くてもリンクタグに、rel="external"
    を付け加えるだけで別ウィンドウで開きますよね
    ジャバスクリプトを使う理由が知りたいのですが?
    それに、外部スクリプトを検索エンジンロボットは読み込みませんよね
    それとrel="external"にすると
    リンク先がnofollowになってしまうのは、自サイトへの影響はないのでしょうか?

    返信削除
  12. rel="external"をつけるだけでは、別ウィンドウで開きません。
    javascriptを使ってページをロードした際に、rel属性がexternalのa要素を拾ってきて、targetを_blankにセットしているんです。
    また、rel="external"とnofollowは無関係です。
    externalにしてもnofollowになることはないかと思います。

    返信削除
  13. スクリプト拝見しました。参考にさせて頂いてます。
    別ウィンドウにしてサイズ指定とかてできるものなのでしょうか?

    返信削除
  14. すみません質問させてください。
    当方環境
    WinXP
    ie ver7.0.5730.11
    なのですが、タブブラウザで閲覧すると問題無く別ウィンドウで表示されるのですが、ie7で閲覧すると別ウィンドウで開くのですが、元ページも別ウィンドウと同じページに移動してしまいます。
    当ページの(Opening a link in a new window - the valid way)のリンクでも同じ事が起きてしまいます。
    これはieが原因なのでしょうか?もし解決方法をご存知でしたら、ご教授お願い頂けると幸いです。

    返信削除
  15. すみません質問させてください。
    当方環境
    WinXP
    ie ver7.0.5730.11
    なのですが、タブブラウザで閲覧すると問題無く別ウィンドウで表示されるのですが、ie7で閲覧すると別ウィンドウで開くのですが、元ページも別ウィンドウと同じページに移動してしまいます。
    当ページの(Opening a link in a new window - the valid way)のリンクでも同じ事が起きてしまいます。
    これはieが原因なのでしょうか?もし解決方法をご存知でしたら、ご教授お願い頂けると幸いです。

    返信削除