XREA.COM Logo XREA.COM Ad

Sleipnir2スレ

52l ★:2007/06/02(土) 18:08:49 ID:???
・全てのテキストノードに正規表現でハイライトをかける
>>51の方法は、ノードが再生成されるから色々と駄目な気がする。
スクリプトで割り当てたイベントとかがぶっ飛んだり、iframeが再読込されたりとか。
そこで、DOMツリーをたどり、全てのテキストノードに対してハイライト処理を行うというのを考えた。

var code='('+function(){
function hilightChild(doc,node,ptn){
for(var cn=node.firstChild;cn;cn=cn.nextSibling){
switch(cn.nodeType){
case(3):{
var p=0;
var nv=cn.nodeValue;
nv.replace(ptn,function(found){
var offset=arguments[arguments.length-2];
if(p<offset){
node.insertBefore(doc.createTextNode(nv.substring(p,offset)),cn);
}
if(found){
var elem=doc.createElement('span');
elem.innerText=found;
elem.style.backgroundColor='yellow';
node.insertBefore(elem,cn);
}
p=offset+found.length;
});
cn.nodeValue=nv.substr(p);
break;
}case(1):{
arguments.callee(doc,cn,ptn)
break;
}
}
}
}
p=new RegExp('href','ig');
hilightChild(document,document.documentElement,p);

case(3)以降が、各テキストノードに対してハイライト処理を行う部分。
nodeValueに対してString.replace()を適用する。一致箇所が見つかるごとに、第2引数に渡した関数が呼ばれる。
関数の中では、対象ノードの前に前回一致から今回一致までの間のテキストをテキストノードとして挿入し、innerTextにマッチ文字列を入れたspan要素を挿入する。
childNodesをfor(...;i<l;i++)で回していると、要素が増えることによるインデックスの変化が生じてややこしいので、firstChildとnextSiblingでチェックするようにした。

body.innerHTMLの置換に比べるとかなり遅いが、まだSleipnirのハイライトよりは速いような気がする。
57KB
名前: E-mail:
ファイル:
0ch BBS 2005-10-08