「はてブのしっぽ」実験中 ― 2007年01月22日 19時08分39秒
概要
もう既にお気づきかと思われますが (初見の人はワカランだろうけどw)、ハイパーリンクのリンク先 URI がはてなブックマークにてブックマークされている場合に (っていうか動作的にはされてなくてもなんだけど)、ブックマークページへリンクする、ブックマークでの参照数を表す画像を、ハイパーリンクのお尻にしっぽのようにくっつけてしまうスクリプトを書いてみました。
流石ブログだけあってカレンダーメニューだのなんだのやたらとハイパーリンクが多いために微妙に動作が重たくなっておりますが、この辺は改良の過程で動作対象のフィルタリング機能とか追加していく方向で解決することとして、とりあえず「実験中」ということで公開だけしてしまうことにします (^_^; 。
使い方
スクリプトを任意のサーバーに up した上で、以下のような HTML 文をどこかしらに書いておけば ok です。
<script type="text/javascript" src="(upしたサーバーのURI)/hatebutail.js" charset="UTF-8"></script>
annopop.js、citelabel.js との併用も可能です。但し、これらとセットで使う場合、hatebutail.js は一番最後にロードするようにした方がいいかもしれません(annopop.js より先にロードした場合、annopop.js が処理しなければならない <a>
タグの数が無駄に増える分動作が重くなるかもしれません。そして citelabel.js より先にロードした場合、citelabel.js が生成する参照先 URI へのハイパーリンクは「はてブのしっぽ」の処理対象外になってしまいます。)。
(追記: Tue Jan 23 00:19:56 JST 2007) (更に追記&変更: Mon Feb 12 08:04:18 JST 2007) 早速というかやっぱりというかクレームが来ちゃったので (^_^; 、フィルタリングを実装しますた。以下の要領で配列をセットすると、該当する ID やクラス名やタグ名を持つ要素の配下にある <a>
タグは、処理の対象外となります。
<script type="text/javascript" src="http://example.com/foo/bar/hatebutail.js" charset="UTF-8"></script> <script type="text/javascript"><!-- Hatebutail.filterId = [ "sidemenu-osusume" ]; // ID Hatebutail.filterClass = [ "calendar", "mod-category", "mod-backno" ]; // クラス名 Hatebutail.filterTagName = [ "h1" ]; // タグ名 //--></script>
更に、以下の要領で配列をセットすると、該当する ID やクラス名やタグ名を持つ要素の配下にある <a>
タグのみが処理の対象になります (つまり、それ以外は処理の対象外になります)。
<script type="text/javascript" src="http://example.com/foo/bar/hatebutail.js" charset="UTF-8"></script> <script type="text/javascript"><!-- Hatebutail.targetId = [ "sidemenu-osusume" ]; // ID Hatebutail.targetClass = [ "calendar", "mod-category", "mod-backno" ]; // クラス名 Hatebutail.targetTagName = [ "h1" ]; // タグ名 //--></script>
つか、今気がついたんだけど、 (←結局変えちゃいました)HatebutailOnLoad
って、変な名前だね。後で名前変えちゃうかも。(今日はもう寝るけど)
動作内容
<a>
タグのhref
属性に書かれた URI は、絶対指定であろうが相対指定であろうが動作対象となります。href
属性が絶対指定の場合、対象となるスキームはhttp(s)
とftp(s)
だけです (mms
も加えた方がいい?)。about
とかjavascript
とかmailto
とかは対象外です。- URI にアンカー名 (
で始まる名前) が含まれる場合、#
を#
に置き換えて処理します (すなわち、アンカー名を含む URI へのブックマークにも対応します)。%23
メモ
document.getElementsByTagName
が返すものおいらはこれはずっと配列なのだと思っていたのですが、どうやら違うもののようです。今回のプログラムを書く上で、最初、以下のように書こうとしていたのですが、
var anchors = document.getElementsByTagName("a"); for (var i = 0; i < anchors.length; i++){ // (いろいろな処理...) var hatebu_anchor = document.createElement("a"); // はてブ用のハイパーリンクを生成 // (...) }
動かしてみると、フリーズしてしまう。で、何でかっていうと、どうやら
document.getElementsByTagName()
は参照を返しているらしく、ループの中で<a>
要素を作ると、その度にanchor.length
も増えてしまい、それでいつまで経ってもfor
ループから抜けられないという無限ループの罠にはまっていたわけです。で、仕方がないので、じゃあ配列をコピーしようか、ということになって、ちょっと調べて、どうやら Javascript では配列は以下のいずれかの方法でコピーできるらしいということを知り、試してみたわけなのですが、
var anchors_tmp = document.getElementsByTagName("a"); var anchors = anchors_tmp.slice(0); // --- (1) var anchors = Array.apply(null, anchors_tmp); // --- (2)
これがなんと、(1) の方法でも (2) の方法でもエラーになってしまい、実行されない (!!)。で、なんでじゃろうと思って Firefox のエラーコンソールを覗いてみると、「
anchors_tmp
にslice
なんてメソッドはねーよ」とか「Array.apply
の第 2 引数にArray
じゃないもん寄越すな」とかおっしゃられる。え、こいつって配列なんじゃないの!? と思って、念のために
var anchors_tmp = document.getElementsByTagName("a"); alert(typeof anchors_tmp);
ってしてみたら、
なんてこたぁない、ふつーに「(訂正: Tue Jan 23 00:47:47 JST 2007 ...object
」って表示されやがった"object"
って表示されるのは当たり前です、Array
もtypeof
は"object"
だし) (Javascript にはArray
がArray
であることを確認する確たる方法ってないんだっけ? メソッド単位で存在するかどうかを確認するぐらいしかないのかしら?)。なるほど、確かに調べてみると、
document.getElementsByTagName
はNodeList
オブジェクトを返すとあるし (でもそれが「参照」なのか「クローン」なのかまでは規定されてないっぽいなぁ。。。A new NodeList object
って書いてあるぐらいだから、むしろ呼び出すたびに生成してそうなイメージなんだけど。。。)、NodeList
オブジェクトについても確かにindex
(角カッコによる添字) とlength
しか用意されていないという、なるほどArray
とはまったくの別物ということになってる。むぅ。で、実際どうやったのかは、まぁ、ソースを参照ってことで。
<a>
タグの DOM ノードオブジェクトにhref
なんて便利なプロパティが存在する件つか、
HTMLAnchorElement
なんつって定義されてるのね。The absolute URI
ってなってるから DOM Level 2 的には「絶対パス」であることが保証されてるっぽい。つか、DOM の仕様ちゃんと読もうな>ヲレ (-_-; 。
(v1.0.3) フィルタリング機能を追加しますた。このサイトでもいくつかフィルタリングを適用しますた。少しは軽くなったかな。。。?
(v2.0.0) フィルタリング機能を強化しました。このサイトも、これで大分軽くなった…ハズ。
コメント
_ @DRK ― 2007/01/22 23:17:21
_ T.MURACHI ― 2007/01/23 00:34:42
つか、これに関してのみいうと、IE は結構処理が重いかも (^_^; 。
_ T.MURACHI ― 2007/01/23 00:47:01
同じ設定同士ならたぶんパフォーマンスはそんなに変わらないと思う。
※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。
※投稿には管理者が設定した質問に答える必要があります。
トラックバック
※トラックバックの受付件数を超えているため、この記事にトラックバックを投稿することができません。