2004年10月29日

JavaScript で複数箇所のキーワードをハイライト

JavaScript で複数箇所の キーワードハイライトさせるいい方法ないすかーと miyagawa氏に訊いたところ、 次のようなコードをさらっと書いてくれた。 キーワードにマウスカーソルを載せると、複数箇所に出現するキーワードが一斉に ハイライトされるというもの。

 
<script>
function hlclass(name, flag) {
    var t = document.getElementsByTagName('span');
    for (var i = 0; i < t.length; i++) {
        if (t[i].className == name) {
            t[i].style.backgroundColor = 
                (flag ? "yellow" : "white");
        }
    }
    return true;
}
</script>
このような関数を定義しておいて、ハイライトしたい キーワードには 次のように class と onmouseover と onmouseout を設定しておく。
<span class="x" 
onmouseover="hlclass('x', 1)" onmouseout="hlclass('x', 0)">x</span>
<span class="x" 
onmouseover="hlclass('x', 1)" onmouseout="hlclass('x', 0)">x</span>
<span class="y" 
onmouseover="hlclass('y', 1)" onmouseout="hlclass('y', 0)">y</span>
<span class="y" 
onmouseover="hlclass('y', 1)" onmouseout="hlclass('y', 0)">y</span>
このエントリーでは「キーワード」と 「ハイライト」とのところに <span...> を設定してあるので、 それらにマウスカーソルをあわせると、それぞれの出現個所が同時に ハイライトされるはずである (IE と Firefox で動作確認した)。

このままだと巨大なページのときに反応が遅くなるので、そういう場合は 次のような感じに途中の処理をキャッシュしてやれば多少はましになる。

var highlightColor = ”yellow";
var backgroundColor = "white";

var cache;
function initCache () {
    cache = new Array();
    var spans = document.getElementsByTagName('span');
    for (var i = 0; i < spans.length; i++) {
        var name = spans[i].className;
        if (!cache[name]) {
            cache[name] = new Array();
        }
        cache[name].push(spans[i]);
    }
}

function hlclass (name, flag) {
    if (!cache) {
        initCache();
    }
    for (var i = 0; i < cache[name].length; i++) {
        cache[name][i].style.backgroundColor =
            (flag ? highlightColor : backgroundColor);
    }
    return true;
}