Hatena::Groupsubtech

冬通りに消え行く制服ガールは✖夢物語にリアルを求めない。

 | 

Apr 26, 2008 (Sat)

日付っぽいもの全てに、現在からの相対時間を付与する 01:48 はてなブックマーク - 日付っぽいもの全てに、現在からの相対時間を付与する - 冬通りに消え行く制服ガールは✖夢物語にリアルを求めない。

	var walker = document.createTreeWalker(
		document.body,
		NodeFilter.SHOW_TEXT,
		{
			acceptNode : function (node) {
				return NodeFilter.FILTER_ACCEPT;
			}
		},
		false
	);

	var hits = [];

	while (walker.nextNode()) {
		var node = walker.currentNode;
		var str  = walker.currentNode.nodeValue;
		var m    =  /(\d{4})-(\d\d)-(\d\d)|(\d+)年(\d+)月(\d+)日/.exec(str);
		if (m) {
			var time = new Date(
				+(m[1] || m[4]),
				+(m[2] || m[5]) - 1,
				+(m[3] || m[6])
			);

			hits.push({
				match: m,
				node: node,
				date: time
			});
		}
	}

	for (var i = 0, len = hits.length; i < len; i++) {
		var m    = hits[i].match;
		var node = hits[i].node;

		var surround = document.createElement("span");

		var range = document.createRange();
		range.setStart(node, m.index);
		range.setEnd(node, m.index + m[0].length);
		range.surroundContents(surround);

		var info = document.createElement("span");
		var style = info.style;
		style.position = "relative";
		style.top      = "-0.5em";
		style.fontSize = "80%";

		var diff = (new Date()).getTime() - hits[i].date.getTime();
		day = Math.floor(diff / 1000 / 60 / 60 / 24);
		info.appendChild(document.createTextNode("("+day+"日前)"));
		surround.appendChild(info);
	}

obsolete フラグ を見ていて、とりあえず相対時間表示がほしいなぁとおもったので userscript かいた。けど、なんか日本語が Greasemonkey でうまいことマッチしなくてめんどくなった……

TreeWalker で nextNode よんでるところと、実際 DOM を操作しているところを別にしているのは、DOM で子要素にまたマッチするノードを追加したりすると、nextNode() でそれがヒットしてっていう無限ループになるからです (なんか回避策あるのかな)。あとは普通に Range つくってるだけ…… クロスブラウザとか考えたらこんな簡単には書けないだろうなぁ

nextNode よぶ位置だけかえてワンパスにしてみた

	var walker = document.createTreeWalker(
		document.body,
		NodeFilter.SHOW_TEXT,
		{
			acceptNode : function (node) {
				return NodeFilter.FILTER_ACCEPT;
			}
		},
		false
	);

	var node = walker.nextNode();
	while (node) {
		var str  = node.nodeValue;
		var m    =  /(\d{4})-(\d\d)-(\d\d)|(\d+)年(\d+)月(\d+)日/.exec(str);
		var next = walker.nextNode();
		if (m) {
			var time = new Date(
				+(m[1] || m[4]),
				+(m[2] || m[5]) - 1,
				+(m[3] || m[6])
			);

			var surround = document.createElement("span");

			var range = document.createRange();
			range.setStart(node, m.index);
			range.setEnd(node, m.index + m[0].length);
			range.surroundContents(surround);


			var info = document.createElement("span");
			var style = info.style;
			style.position = "relative";
			style.top      = "-0.5em";
			style.fontSize = "80%";

			var diff = (new Date()).getTime() - time.getTime();
			day = Math.floor(diff / 1000 / 60 / 60 / 24);
			info.appendChild(document.createTextNode("("+day+"日前)"));
			surround.appendChild(info);
		}
		node = next;
	}
 | 

スポンサード リンク

書いてる人

cho45 (佐藤広央) (www.lowreal.net)

Perl, JavaScript, Ruby, HTML, CSS, Web etc


スポンサード リンク