にしし ふぁくとりー:西村文宏 個人サイト

"JavaScript Tips Factory" : Presented by Nishishi. Since 1997.

表示文章中の、指定の単語だけを動的に強調表示(ハイライト)する方法 [装飾・内容変更]

ウェブページに掲載されている文章の中から、指定の単語だけを動的にハイライトしたり消したりする機能をJavaScriptで作る方法を解説。文章中の単語に最初からハイライトを加えていると読みにくくなる可能性がありますから、標準では何もせず、閲覧者がハイライトする意思を示したときにだけハイライトするような仕組みを設けておく方が使いやすいでしょう。ボタンを押す度に、ハイライトのONとOFFが切り替わるようにする作り方をご紹介。

指定の単語だけを動的に強調表示(ハイライト)したい

ウェブページに掲載されている文章の中から、指定の単語だけに動的にハイライトを加えたいことがあります。文章中の重要単語を強調したい場合とか、ユーザが探している文字列の場所を示したい場合とか、様々な用途があるでしょう。

最初からハイライトした状態で表示すると文章が全体的に読みにくくなる可能性がありますから、標準では何もせず、閲覧者がハイライトする意思を示したときにだけハイライトするような仕組みを設けておく方が使いやすい気がします。もしくは、標準ではハイライトしておいて、ユーザが手動でハイライトをOFFにできる仕組みを設けておくのでも良いと思いますが。

ボタンクリックでハイライトをON/OFFする動作例

動作例は以下のような感じです。緑色の文章枠の下にある「ハイライトON/OFF」ボタンを押してみて下さい。押す度に、ハイライトONとハイライトOFFが切り替わります。

この枠内に表示されている文章に対して、指定の単語だけをハイライトします。ハイライトのON/OFFはボタンで切り替えられます。この枠の外に表示されている文章はハイライトの対象外です。JavaScriptを使ってハイライトしているため、CGIなどの仕組みは不要です。掲示板のように「新たに文章が追加される環境」で、CGIやPHPなどのソースを弄らずに自動ハイライト機能を加えたい場合などに利用できるでしょう。

上記の動作サンプルは、下記のように動作するはずです。

  • 何もハイライトされていない状態で「ハイライトON/OFF」ボタンを押すと、文章中にある「ハイライト」が黄色に、「文章」が緑色に、「表示」が水色にそれぞれハイライトされる。
  • 既にハイライトされている状態で「ハイライトON/OFF」ボタンを押すと、すべてのハイライト表示が消える。

■動作イメージ:
(左)ハイライトなしの初期状態/(右)ハイライトした状態
▲(左)ハイライトなしの初期状態 / (右)ハイライトした状態

今回は、このような動的なハイライト機能をJavaScriptで作る方法を紹介します。わりと簡単です。

動的ハイライト対象のHTMLソースを書く

まずは、HTMLソースを記述します。が、HTMLソースに特別な点はほぼありません。対象の文章を好きなように記述するした上で、ハイライト制御用のボタンを1つ作るだけです。後からJavaScriptで扱うためにid属性を使って任意のid名を割り振っておきます。また、CSSで装飾するためにclass名を加えていますが、class名の付加は必須ではありません。

HTMLソース

<p id="targetspace">
	この枠内に表示されている文章に対して、指定の単語だけをハイライトします。ハイライトのON/OFFはボタンで切り替えられます。……
</p>
<p class="controlpane">
	<input type="button" value="ハイライトON/OFF" id="btn-onoff">
</p>

上記のHTMLソースでは、

  • ハイライト対象の文章として、p要素に属性id="targetspace"を付加しています。(1行目)
  • また、ハイライトON/OFFボタンは、input要素で作っており、属性id="btn-onoff"を付加しています。(5行目)

次に、ハイライト装飾用のCSSを作っておきます。

動的ハイライト表示のためのCSSソースを書く

次に、CSSソースを記述します。文章枠やボタン枠の装飾も含んでいるので長くなっていますが、必須なのはハイライトを加える部分である18行目~20行目の3行だけです。この3行は、単にハイライトの配色を3種類用意しているから3行あるのであって、1色しか使わないなら1行で済みます。

CSSソース

/* ▼対象文章枠の装飾(任意) */
#targetspace {
	border: 2px solid #0a0;  /* 枠線 */
	border-radius: 0.67em;   /* 角丸 */
	padding: 0.5em;          /* 内側余白 */
	width: 100%;             /* 横幅 */
	box-sizing: border-box;  /* はみ出しを防ぐ対策 */
	background-color: #fff;  /* 背景色 */
	line-height: 1.6;        /* 行の高さ */
}
/* ▼ハイライトON/OFFボタン枠の装飾(任意) */
.controlpanel {
	margin: 1em 0;           /* 外側余白 */
	padding: 1em;            /* 内側余白 */
	background-color: #eee;  /* 背景色 */
}
/* ▼ハイライト部分の装飾 */
span.mark1 { background-color: yellow; } /* 黄色ハイライト用 */
span.mark2 { background-color: lime; }   /* 緑色ハイライト用 */
span.mark3 { background-color: #0ff; }   /* 水色ハイライト用 */

上記のCSSソースのポイントをざっと解説しておきます。

  • 2行目~10行目: 対象文章に枠を設けているだけです。特に書かなくても構いません。
  • 12行目~16行目: ハイライトON/OFFボタン枠を設けているだけです。特に書かなくても構いません。
  • 18行目~20行目: ハイライトを3種類作っています。ハイライトと言っても、単に背景に明るい蛍光ペンのような色を付加しているだけです。

CSSは以上です。
次に、メインのJavaScriptソースを書きましょう。

ハイライトを加えたり消したりするためのJavaScriptソースを書く

まずは、JavaScriptソースすべてを掲載しておきます。

JavaScriptソース

// ▼①元のHTMLソースを保持しておく変数
var backupOriginal = "";
// ▼②文字列を検索してハイライト用要素を加える処理
function replacer( str, word , att  ) {
	var SearchString = '(' + word + ')';
	var RegularExp = new RegExp( SearchString, "g" );
	var ReplaceString = '$1';
	var ResString = str.replace( RegularExp , ReplaceString );
	return ResString;
}
// ▼③ハイライトを加える処理
function addhighlight() {
	backupOriginal = document.getElementById("targetspace").innerHTML;
	var forShow = backupOriginal;
	forShow = replacer( forShow, "ハイライト", "mark1" );
	forShow = replacer( forShow, "文章", "mark2" );
	forShow = replacer( forShow, "表示", "mark3" );
	document.getElementById("targetspace").innerHTML = forShow;
}
// ▼④ハイライトを消す処理
function clearhighlight() {
	document.getElementById("targetspace").innerHTML = backupOriginal;	// バックアップから書き戻す
	backupOriginal = "";	// バックアップを消す
}
// ▼⑤ハイライトを加えるか消すかを判断
function highlightcheck() {
	if( backupOriginal.length == 0 ) {
		// 何もバックアップされていなければ(未ハイライトなので)ハイライトを加える
		addhighlight();
	}
	else {
		// 何かバックアップされていれば(ハイライト済みなので)ハイライトを消す
		clearhighlight();
	}
}
// ▼⑥ボタンクリックイベントに、上記の関数を割り当てる
document.getElementById("btn-onoff").onclick  = highlightcheck;

最初に、①の部分でグローバル変数を1つ用意しています。この変数backupOriginalは、「ハイライトしない状態のHTMLソース」を保存しておくために使っています。また、この変数backupOriginalの中身が空っぽの場合は「まだハイライト指定ない」と解釈し、中身がある場合は「既にハイライトしている状態だ」と解釈し、条件分岐にも使っています。

続いて、以下の4つの関数を作成しています。

最後に、⑥の部分で「ハイライトON/OFFボタン」のonclickイベントに⑤の関数を割り当てることで、ボタンクリックでハイライトのON/OFF処理が実行されるようにしています。
4つの関数の処理内容については、下記で個別に解説しておきます。

文字列を検索してハイライト用要素を加える処理

対象の文章中から指定の文字列を探して、ハイライト表示するためのspan要素でマークアップする処理をする、関数「replacer」を作ります。

JavaScriptソース(抜粋)

// ▼②文字列を検索してハイライト用要素を加える処理
function replacer( str, word , att  ) {
	var SearchString = '(' + word + ')';
	var RegularExp = new RegExp( SearchString, "g" );
	var ReplaceString = '$1';
	var ResString = str.replace( RegularExp , ReplaceString );
	return ResString;
}

この関数では引数を3つ取り、

  • 第1引数 str :対象の文章全文
  • 第2引数 word:ハイライトする単語
  • 第3引数 att :ハイライトするためのCSS属性値

という仕様になっています。
変数strの中身に対して、正規表現を使って文字列wordを探し、見つかった全ての文字列に対して <span class="属性値">単語</span> のようにspan要素でマークアップを加えています。

なお、正規表現部分については、別途記事「正規表現を使って文字列を置換する方法」で解説していますので、そちらをご参照下さい。
ここでは、JavaScriptソースをそのままコピー&ペーストするだけで使えます。

対象単語にハイライトを加える処理

次に、対象の文章中から指定単語にハイライトを加えるメイン処理をする、関数「addhighlight」を作ります。引数はありません。

JavaScriptソース(抜粋)

// ▼③ハイライトを加える処理
function addhighlight() {
	backupOriginal = document.getElementById("targetspace").innerHTML;
	var forShow = backupOriginal;
	forShow = replacer( forShow, "ハイライト", "mark1" );
	forShow = replacer( forShow, "文章", "mark2" );
	forShow = replacer( forShow, "表示", "mark3" );
	document.getElementById("targetspace").innerHTML = forShow;
}

ここでは例として、文字列「ハイライト」を黄色に、文字列「文章」を緑色に、文字列「表示」を水色にハイライトしています。それを指定しているのが、15行目~17行目の3行です。これらは必要に応じて修正・追加・削除して下さい。
上記の処理内容はだいたい以下のような感じです。

  • 13行目: idとしてtargetspaceが指定された要素の中身(HTMLソース)を丸ごと取得して、変数backupOriginalに格納(バックアップ)。
  • 14行目: その内容をそのまま変数forShowにもコピー。
  • 15行目~17行目: 変数forShowを対象にして、ハイライトを追加。(ここの書き方は、後述する「ハイライト対象を増減させる」もご参照下さい。
  • 18行目: 変数forShowの内容を、idとしてtargetspaceが指定された要素に代入。

18行目の処理によって、表示されている文章の内容が置き換わります。

すべてのハイライトを消す処理

次に、ハイライトを消す処理をする、関数「clearhighlight」を作ります。引数はありませんし、処理内容も単純にバックアップしておいた内容を書き戻すだけです。

JavaScriptソース(抜粋)

// ▼④ハイライトを消す処理
function clearhighlight() {
	document.getElementById("targetspace").innerHTML = backupOriginal;	// バックアップから書き戻す
	backupOriginal = "";	// バックアップを消す
}

ハイライト用のマークアップを加える前の状態は、変数backupOriginalに保存してありますから、その内容を「idとしてtargetspaceが指定された要素」へ代入するだけです。(22行目)
なお、ハイライトがOFFであることを示すために、変数backupOriginalの中身を空っぽにしています。(23行目)

ハイライトを加えるか消すかを判断(ボタンクリックに割り当て)

最後に、ハイライトON/OFFボタンがクリックされた際の処理を記述します。ボタンは1つだけなので無名関数で作っても良いのですが、まあ、分割した方がソースが見やすいかと思って独立した関数「highlightcheck」として作りました。

JavaScriptソース(抜粋)

// ▼⑤ハイライトを加えるか消すかを判断
function highlightcheck() {
	if( backupOriginal.length == 0 ) {
		// 何もバックアップされていなければ(未ハイライトなので)ハイライトを加える
		addhighlight();
	}
	else {
		// 何かバックアップされていれば(ハイライト済みなので)ハイライトを消す
		clearhighlight();
	}
}
// ▼⑥ボタンクリックイベントに、上記の関数を割り当てる
document.getElementById("btn-onoff").onclick  = highlightcheck;

ハイライトON/OFFボタンは、クリックする度にハイライトのONとOFFを切り替える、トグル式ボタンです。
「今ハイライトされているか?」は、バックアップ用変数backupOriginalの中身が空っぽかどうかで判断します。それが、27行目のif文です。lengthプロパティの値を参照して、ゼロなら空っぽだと判断できます。あとは、以下のように2通りの判定と実行をするだけです。

  • 何もバックアップされていなければ(未ハイライトなので)ハイライトを加える関数「addhighlight」を実行する。
  • 何かバックアップされていれば(ハイライト済みなので)ハイライトを消す関数「clearhighlight」を実行する。

37行目で、これらの処理をボタンクリックに割り当てています。
このスクリプトが実行されるよりも前に、id="btn-onoff"の付加されたHTMLソースが読み込まれている必要がありますので、記述順に注意して下さい。

ハイライト対象を増減させる

ハイライト対象の文字列を増やすには、forShow = replacer( forShow, "ハイライト対象", "適用する装飾" );の書き方で必要なだけ列挙すれば済みます。
その結果、「ハイライト対象」という文字列が <span class="適用する装飾">ハイライト対象</span> のようにマークアップされます。適用する装飾の部分は、あらかじめCSSで指定しておいたハイライト用のclass名です。

例えば、15行目は以下のように書いていました。

JavaScriptソース(抜粋)

forShow = replacer( forShow, "ハイライト", "mark1" );

この処理が実行されると、対象文中にある「ハイライト」という文字が、以下のHTMLのようにマークアップされます。

JavaScript実行結果として生成されるHTML

<span class="mark1">ハイライト</span>

ハイライト対象の文字列や色をユーザ自身が指定できるようになっているとより便利だとは思いましたが、ちょっとソースが長くなるのでここでは決め打ちで作りました。
せめて、ハイライト対象の文字列と装飾内容を配列に格納しておくように作ったら便利だったかもしれませんけどもね。(^_^;)

以上、表示文章中の「指定の単語」だけを動的に強調表示(ハイライト)する機能の作り方でした。
ぜひ、試してみて下さい。

()

JavaScript TIPSふぁくとりーの主要なカテゴリ

下記のカテゴリに区分して、JavaScriptに関するTIPSを公開しています。カッコ内の数字は、該当する記事の件数です。

著者紹介


にしし(西村文宏)

にししでございます。本書いたり記事書いたりしてます。あと萌えたり。著書5冊発売中です(Web製作系4冊+小説1冊)。著書や記事は「西村文宏」名義。記事は主にAll Aboutで連載。本の最新刊は2011年3月に発売されたライトノベルでございますよ。

Twitter:にしし/西村文宏
にしし/西村文宏 on facebook にしし/西村文宏 on mixi フォローはお気軽に!

にしし(西村文宏)連絡先
☕ コーヒーをおごる

著書一覧と詳細

関連するかもしれない情報など

▼このページに関連しそうな記事が約8本くらい自動表示されています。(たぶん)

--- 当サイト内を検索 ---