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; }