現在のスクロール位置が、読み込み開始位置を超えていないかチェック。閾値を超えたらリクエストを投げる

※現在のスクロール位置が、読み込み開始位置を超えていないかチェック。閾値を超えたらリクエストを投げる

http://d.hatena.ne.jp/taizooo/20090509/1241796655

addEventListener とかスクロール位置がなんたらかんたら、っていうのが全然わかってないのでまずはもっと簡単な os0x の twitter.AutoPager を見てみるか。

なんか ver 0.4 になっててコードの行数が増えておる。あれだ、follower と following で通常の AutoPagerize と同じ動作をするようなコードが追加されてるんだ。古い方を参考にしよう。

// ==UserScript==
// @name           twitter.AutoPager
// @namespace      http://ss-o.net/
// @version        0.3
// @include        http://twitter.com/*
// @include        https://twitter.com/*
// ==/UserScript==

// Thx! id:Constellation
(function autopager(unsafeWindow,loaded){
	if (!loaded && window.opera && document.readyState == 'interactive') {
		document.addEventListener('DOMContentLoaded', function(){autopager(unsafeWindow,true);}, false);
		return;
	}
	if(!get_more()) return;
	var state = true;
	var remainHeight = 400;
	var loading = false;
	var win = this.contentWindow || window;
	var filters = [];
	if (!win.AutoPagerize) {
		win.AutoPagerize = {
			addFilter:function(f) {
				filters.push(f);
			}
		};
	}
	var ev = document.createEvent('Event');
	ev.initEvent('GM_AutoPagerizeLoaded', true, true);
	document.dispatchEvent(ev);
	var last = get_last_line();
	var filter = function(){
		loading = false;
		var docs = get_inserted_line(last.id);
		filters.forEach(function(f){
			f(docs);
		});
		last = get_last_line();
	};

	if (typeof unsafeWindow.onPageChange === 'function') {
		var _onPageChange = unsafeWindow.onPageChange;
		unsafeWindow.onPageChange = function(){
			_onPageChange();
			filter();
		};
	} else {
		unsafeWindow.onPageChange = filter;
	}
	window.addEventListener('scroll', function(){
		if (loading) return;
		var remain = document.documentElement.scrollHeight - window.innerHeight - window.pageYOffset;
		if (state && remain < remainHeight)
			click_more();
	}, false);
	function click_more(){
		var event = document.createEvent('MouseEvents');
		event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
		get_more().dispatchEvent(event);
		loading = true;
	}
	function get_more(){
		return document.getElementById('more');
	}
	function get_last_line(){
		return document.evaluate('id("timeline")/li[last()]',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
	}
	function get_inserted_line(id){
		var x = 'id("timeline")/li[preceding-sibling::li[@id="'+id+'"]]';
		var res=[],r = document.evaluate(x,document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
		for (var i = 0,l = r.snapshotLength;i<l;i++) res.push(r.snapshotItem(i));
		return res;
	}
})(this.contentWindow||this.unsafeWindow||window,0);

再開

	window.addEventListener('scroll', function(){
		if (loading) return;
		var remain = document.documentElement.scrollHeight - window.innerHeight - window.pageYOffset;
		if (state && remain < remainHeight)
			click_more();
	}, false);

addEventListener と document.documentElement.scrollHeight と window.innerHeight と window.pageYOffset だな。

  1. document.documentElement.scrollHeight は、その html 文書の高さ(px)で
  2. window.innerHeight は、ブラウザで表示しているウインドウの高さ(px)で
  3. window.pageYOffset は、 window.scrollY のエイリアスで、文書の上からどんだけスクロールダウンか(px)

なので var remain = document.documentElement.scrollHeight - window.innerHeight - window.pageYOffset; は、ウインドウに表示されている下端から文書の一番下までの高さ(px)のことなのね。で、これを remainHeight (この場合 400px )と比べてそれより小さくなったら click_more を実行するということだ。

さーて今度は addEventListener だ。