HTMLの文章をハイライト表示させるJScript

Googleツールバーのハイライトのようなことがスクリプトでできないかと考えた。

innerHTMLを丸ごと置換するだけでは、タグごと置換してしまうので
innerHTMLとinnerTextを比べながら、タグでない場所のみ置き換えてみた。

・・・効率わるっ(T_T)

使い方


<!-- インクリメンタルハイライト -->
<input id='word' onkeyup="onHigthLight( text_subject, this.value, 'yellow' );"><br>
<!-- ボタンを押したらハイライト -->
<input id="word2" NAME="Text1" >
<input type='button' onclick="onHigthLight(text_subject, word2.value,'blue')" value='検索'>

<div id='text_subject'>
ハイライトさせたい文字列〜〜〜
この中の文字列をむりやり
ハイライトさせます
</div>

ハイライトさせるソース


// 置換する前の値を保存するための文字列
var originHTML = "";
var originText = "";

/**
* 無理やりハイライトするJavaSript
* タグにマッチさせないようにするため、innerHTMLとinnerTextを比較しながら
* 1文字ずつ進めて、Textのみ置換するように強引にやってます
*
* subj 置換対象オブジェクト(body, div, span など)
* word 検索文字列
* hcolor ハイライト色
*/

function onHigthLight( subj, word, hcolor )
{
// 一度目のみオリジナルを保存
if( originHTML.length == 0 )
{
originText = subj.innerText ;
originHTML = subj.innerHTML;
}

// 検索文字列が2文字以下ではハイライトさせない
if( word.length < 2 )
{
subj.innerHTML = originHTML;
return;
}

// 走査するためのワーク変数
var innerText = originText;
var innerHTML = originHTML;

// 文字を進めるインデックスと長さ
var idxT, idxH;
idxT = idxH = 0;
var tLen = innerText.length;
var hLen = innerHTML.length;

var tmpHTML, tmpText;
tmpHTML = "";
tmpText = "";


// 置換する文字列を表す正規表現
var re= new RegExp( word,"g");

// ハイライト用置換テキスト
var highlightText = "<span style='background-color:" + hcolor + "'>" + word + "</span>";

// 置換後の文字列をセットする作業文字列
var replacedHTML = "";
//
while( true )
{
var isLast = (idxT >= tLen) || (idxH >= hLen);
if( isLast )
{
replacedHTML += tmpText.replace( re, highlightText );
break;
}

var isSameChar = innerHTML.charAt(idxH) == innerText.charAt(idxT);
if( isSameChar )
{
// HTML部分のみを抽出したので、そのまま追加する
if( 0 < tmpHTML.length )
{
replacedHTML += tmpHTML;
tmpHTML = "";
}
tmpText += innerText.charAt(idxT);
idxT++;
idxH++;
}
else
{
// テキスト部分のみを抽出した文字列に対して、置換後追加
if( 0 < tmpText.length )
{
replacedHTML += tmpText.replace( re, highlightText );
tmpText = "";
}

// innerHTML = あいう<br> <input type=... >えお
// innerText = あいうえお
// <tag1> <tag2> という、パターンに無理やり対応するための処理
do
{
// ">"まで進める
while( innerHTML.charAt(idxH) != ">" )
{
tmpHTML += innerHTML.charAt(idxH);
idxH++;
if( hLen <= idxH) break;
}
tmpHTML += innerHTML.charAt(idxH);
idxH++;

// スペースだったら進める
while( 0 == innerHTML.charAt(idxH).search(/\s/) )
{
tmpHTML += innerHTML.charAt(idxH);
idxH++;
if( hLen <= idxH) break;
}

// スペースの後ろに'<'が存在する場合は、もう一度タグを飛ばす
}while( innerHTML.charAt(idxH) == '<') ;

// innerTextの先頭にスペースがある場合進める
while( innerText.charAt(idxT) != innerHTML.charAt(idxH) )
{
idxT++;
if( tLen <= idxT) break;
}
}
}

// 置換後の文字列に置き換える
subj.innerHTML = replacedHTML;
}

ちょっとした発見

IMEを使用して日本語入力中の文字列をJavaScriptから拾う方法発見!
(変換中で下に線がついている状態で)


<script>

function func( arg1 )
{
// arg1に変換途中の文字列がはいっているw(゜o゜)w!
}
</script>


<input id='hoge'onkeyup="func(this.value);">