AutoPagerizeで継ぎ足された部分に自分のスクリプトを適用する方法あれこれ
以前からある手法から順番に見ていきます。
ページの高さの監視
setIntervalでページの高さを監視して、増えていたらAutoPagerizeが動いたとみなして処理を行う
var THRESHOLD = 300; var _height = window.innerHeight; setInterval(function(){ if (window.innerHeight - _height > THRESHOLD) { // 処理 } _height = window.innerHeight; }, 300);
メリット
AutoPagerizeだけでなく、はてなダイアリー・ブックマーク、Twitterなどでのサイト側でのページの継ぎ足しにも対応できる
デメリット
THRESHOLDをいくつにするかなど、一概に決められない。タイマーをたくさん回すと重くなる。Floatしている要素を継ぎ足した場合など、ページの高さが変わらない場合がある。スマートな方法ではないので、最近は使われません。
DOMNodeInsertedで監視
DOMNodeInsertedイベントを監視して要素が足されたタイミングを捕捉する
document.body.addEventListener('DOMNodeInserted',function(evt){ if (/hoge/i.test(evt.target.className)) { // 処理 } }, false);
メリット
AutoPagerizeだけでなく、はてなダイアリー・ブックマーク、Twitterなどでのサイト側でのページの継ぎ足しにも対応できる
デメリット
補足した要素がAutoPagerizeによるものか(処理の対象とするべきか否か)検証する必要がある。
要素の書き換えを頻繁に行うサイトで重くなる(特にlivedoor Readerなど)。
Tips
特定のサイト用のスクリプトならば、監視対象のノードを限定すると良い。例えばTwitterの場合、
document.getElementById('timeline').addEventListener('DOMNodeInserted',function(evt){ if (/hentry/i.test(evt.target.className)) { // 処理 } }, false);
AutoPagerize APIのaddFilterを使う
AutoPagerize.addFilterは、登録された関数をページの継ぎ足し時に実行してくれる。
var boot = function(){ AutoPagerize.addFilter(function(docs){ docs.forEach(function(node){ if (/hentry/i.test(node.className)) { // 処理 } }); }); }; if (window.AutoPagerize) { boot(); } else { window.addEventListener('GM_AutoPagerizeLoaded',boot,false); }
メリット
引数で継ぎ足された要素を配列として受け取れるので、効率的に足された部分だけを処理できる。
デメリット
addFilterが使えるようになるタイミングに注意しなければいけないので、冗長なコードになる。
GM_AutoPagerizeLoaded以前
GM_AutoPagerizeLoadedが実装される前はsetTimeoutで監視する方法が使われていた。今でもこのタイプのスクリプトは多い。(Firefox限定ではsetTimeoutを1回挟めば確実にwindow.AutoPagerizeを取れるが、Google Chromeでは失敗することがあるので注意が必要。下記のように数回実行すると良い)
var init = function(count){ if (!window.AutoPagerize) { if (count > 0) { setTimeout(init, 300, count - 1); } return; } AutoPagerize.addFilter(function(docs){ docs.forEach(function(node){ if (/hentry/i.test(node.className)) { // 処理 } }); }); }; init(4);
AutoPagerize Event APIの AutoPagerize_DOMNodeInserted を使う
AutoPagerize_DOMNodeInserted イベントは、名前の通りAutoPagerize独自のDOMNodeInsertedイベントで、追加された要素をtargetとしたイベントが発火される。
document.body.addEventListener('AutoPagerize_DOMNodeInserted',function(evt){ var node = evt.target; var requestURL = evt.newValue; var parentNode = evt.relatedNode; // 処理 }, false);
メリット
追加されたノードを効率的に処理できる。
実行順を気にする必要がないのでコードがシンプル
デメリット
最新バージョンのAutoPagerize(version 0.40 以降)、jAutoPagerize(Rev: 33889+ 以降)でないと対応していない
Tips
AutoPagerize_DOMNodeInsertedは元々oAutoPagerizeで実装したものなので、当然oAutoPagerizeでも使用できます。(oAutoPagerizeに実装する際には例によってnanto_vi先生にアドバイスを頂き、AutoPagerize、jAutoPagerizeの実装もnanto_vi先生のPatchによるものです。nanto_vi++ )
twitter.AutoPager for GreasemonkeyもAutoPagerize_DOMNodeInsertedに対応させました。
まとめ
というわけで、今後は AutoPagerize_DOMNodeInserted を推奨したい次第です。
ちなみに、サイト側でAutoPagerizeするときも、これらのEventを投げてくれると嬉しいですね。