「はてブのしっぽ」実験中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.jscitelabel.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 にアンカー名 (# で始まる名前) が含まれる場合、#%23 に置き換えて処理します (すなわち、アンカー名を含む URI へのブックマークにも対応します)。

メモ

  • 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_tmpslice なんてメソッドはねーよ」とか「Array.apply の第 2 引数に Array じゃないもん寄越すな」とかおっしゃられる。

    え、こいつって配列なんじゃないの!? と思って、念のために

    var anchors_tmp = document.getElementsByTagName("a");
    alert(typeof anchors_tmp);
    

    ってしてみたら、なんてこたぁない、ふつーに「object」って表示されやがった(訂正: Tue Jan 23 00:47:47 JST 2007 ... "object" って表示されるのは当たり前です、Arraytypeof"object" だし) (Javascript には ArrayArray であることを確認する確たる方法ってないんだっけ? メソッド単位で存在するかどうかを確認するぐらいしかないのかしら?)。

    なるほど、確かに調べてみると、document.getElementsByTagNameNodeList オブジェクトを返すとあるし (でもそれが「参照」なのか「クローン」なのかまでは規定されてないっぽいなぁ。。。A new NodeList object って書いてあるぐらいだから、むしろ呼び出すたびに生成してそうなイメージなんだけど。。。)、NodeList オブジェクトについても確かに index (角カッコによる添字) と length しか用意されていないという、なるほど Array とはまったくの別物ということになってる。むぅ。

    で、実際どうやったのかは、まぁ、ソースを参照ってことで。

  • <a> タグの DOM ノードオブジェクトに href なんて便利なプロパティが存在する件

    つか、HTMLAnchorElement なんつって定義されてるのね。The absolute URI ってなってるから DOM Level 2 的には「絶対パス」であることが保証されてるっぽい。つか、DOM の仕様ちゃんと読もうな>ヲレ (-_-; 。


Tue Jan 23 00:19:56 JST 2007 - 追記

(v1.0.3) フィルタリング機能を追加しますた。このサイトでもいくつかフィルタリングを適用しますた。少しは軽くなったかな。。。?


Mon Feb 12 08:04:18 JST 2007 - 追記

(v2.0.0) フィルタリング機能を強化しました。このサイトも、これで大分軽くなった…ハズ。

コメント

_ @DRK ― 2007/01/22 23:17:21

微妙というかかなり重たいぞー

_ T.MURACHI ― 2007/01/23 00:34:42

一応ページ全体の半分ぐらいの <a> タグが対象外になるように設定してみたんだが。。。どうでしょ?

つか、これに関してのみいうと、IE は結構処理が重いかも (^_^; 。

_ T.MURACHI ― 2007/01/23 00:47:01

↑ごめん、嘘ついた。重いのはスクリプト自体じゃなくて画像の読み込み処理だから、IE より他が軽く見えたのは、Firefox も Opera も読み込み処理を最適化するオプション設定を施してたからだ。
同じ設定同士ならたぶんパフォーマンスはそんなに変わらないと思う。

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※投稿には管理者が設定した質問に答える必要があります。

名前:
メールアドレス:
URL:
次の質問に答えてください:
おいらがやっている会社の名前をひらがな4文字で。

コメント:

トラックバック

※トラックバックの受付件数を超えているため、この記事にトラックバックを投稿することができません。