Hatena::Groupos0x

FFFF RSSフィード

0xFFのメモです。

2008 March 26th Wednesday

勝手に添削してみる (AutoPagerize対応GMScriptの書き方みたいな)

23:49 | 勝手に添削してみる (AutoPagerize対応GMScriptの書き方みたいな) - FFFF を含むブックマーク はてなブックマーク - 勝手に添削してみる (AutoPagerize対応GMScriptの書き方みたいな) - FFFF

追記:AutoPagerizeで継ぎ足された部分に自分のスクリプトを適用する方法あれこれ - os0x.blogもどうぞ

movatwitterFriendDirectLinkをこっそり添削。

(function () {
var f = function(docs) {
  for (var n = 0,nLen = docs.length;n < nLen;n++) {
    var aTags = docs[n].getElementsByTagName('a');
    for (var i = 0, len = aTags.length;i < len;i++){
      var a = aTags[i];
      if (a.href.match(/user\/\w+\/friend\/(\w+)/)) {
        a.href = 'http://twitter.com/' + RegExp.$1;
      }
    }
  }
}
f([document]);
if (window.AutoPagerize) window.AutoPagerize.addFilter(f);
})();

こんな感じかな。

追記:改めてみると[document]はイマイチだった。addFilterに渡すのを無名関数にして、そこでループするほうがスッキリする

(function () {
var f = function(doc) {
  var aTags = doc.getElementsByTagName('a');
  for (var i = 0, len = aTags.length;i < len;i++){
    var a = aTags[i];
    if (a.href.match(/user\/\w+\/friend\/(\w+)/)) {
      a.href = 'http://twitter.com/' + RegExp.$1;
    }
  }
}
f(document);
if (window.AutoPagerize) window.AutoPagerize.addFilter(function(docs){
  for (var i = 0,l = docs.length;i < l;i++) f(docs[i]);
});
})();

ちょくちょく参照されているみたいなので、もうちょいモダンな書き方に修正。ifの条件式のなかで代入もしてしまうショートコーディングスタイルに。あと、正規表現はmatchではなくexecで効率アップ。そして、GM_AutoPagerizeLoadedでAutoPagerizeより先に実行された場合でもaddFilterできるように修正。

(function () {
var fnc = function(doc) {
  var as = doc.getElementsByTagName('a'), id, a;
  for (var i = 0, len = as.length;i < len; i++){
    if ( (id = /user\/\w+\/friend\/(\w+)/.exec((a = as[i]).pathname)) ) {
      a.href = 'http://twitter.com/' + id[1];
    }
  }
}
fnc(document);
if (window.AutoPagerize) {
  boot();
} else {
  window.addEventListener('GM_AutoPagerizeLoaded',boot,false);
}

function boot(){
  window.AutoPagerize.addFilter(function(docs){
    docs.forEach(fnc);
  });
}

})();

まず、addFilterについて。このメソッドに関数を渡すと、AutoPagerizeが動いたときにその関数を実行してくれるわけですが、引数にページに追加されたElementNodeの配列が渡されてきます(上記のdocs)。繰り返しますが、docs配列なのでループ処理しないといけません。

で、addFilterに渡す関数配列引数にする都合から、最初に実行するときも配列を渡しておくことでちょっと強引に一つの関数を使いまわしています。( f([document]);の部分 )

で、document.getElementsByTagName('a')ではなく、docs[n].getElementsByTagName('a')とすることで、その要素以下のaタグだけを取得しています。つまり、無駄なく未処理のaタグだけを取得しています。これが結構重要。

あとは細かいところで、

  • [a-z0-9_]は\wとほぼ同じなので、\wに。
  • Twitterのusernameは\wと同じなので、ここも\wに ($は不要なので削除)。
  • aTag[i]を何度も参照するより、変数に入れたほうが効率的(高速)なので、変数に入れておく。
  • 配列を回す前に、Array.lengthを一時変数(nLenやlen)に入れているのは、lengthへの参照を減らして高速化する定番Tips。
  • 不要な一時変数(var url = RegExp.$1;)があったので削除

などです。

ホントは、リファラを送らないような方法に書き換えるってのがベストだと思うんだけど、そこまでの気力は出なかった。以上。

taizoootaizooo2008/03/27 11:20アリガトウ!!!勉強になりまっす。
グリモンどころかjavascript、実はなんもわかってなかったりするのでした。コピペと書き換えです。切り貼りは得意なんです。でわでわ。