JavaScript

レシピ

イベント

テキストを選択したときに処理を実行する

ページ内の特定のテキストが選択状態となったときに指定した処理を実行する方法について解説します。

この記事のポイント

  • テキストの選択を開始するとイベントselectstartが発生する
  • タッチ操作する端末でも対応可能
  • フォームの要素ではselectを使う

目次

テキストを選択するとイベントが発生する

ページにあるテキストをマウスで選択すると、選択開始した時点でイベントselectstartが発生します。

テキストを選択開始するとイベントが発生する

イベントselectstartは以下のようにイベントリスナーに登録して使用します。
こちらのコードではp要素内のテキストを対象としています。

コード例

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>GRAYCODE JavaScript</title>
	<script>
		window.addEventListener('DOMContentLoaded', function(){

			document.querySelector("p").addEventListener('selectstart', function(){			
				console.log("テキストが選択されました");
			});

		});
	</script>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1">
<p>テキストの選択にイベントリスナーを設定する</p>
</section>
</body>
</html>

今回は例としてp要素を使っていますが、h1要素など見出し系の要素やdiv要素などで囲ったテキストも同じようにイベントが発生するので、同じ方法でテキストの選択を検知することができます。

選択したテキストを取得する

イベントselectstartは選択開始された状態を検知することはできますが、選択が終わったあとにどの範囲でテキストが選択されたかまでは分かりません。
そこで、次のようにイベントmouseupと組み合わせることで、実際に選択されたテキストを取得することができるようになります。

コード例

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>GRAYCODE JavaScript</title>
	<script>
		window.addEventListener('DOMContentLoaded', function(){
			
			var p_element = document.querySelector("p");

			p_element.addEventListener('selectstart', function(){
				p_element.addEventListener('mouseup', function(event) {
					console.log(window.getSelection().toString());
				});
			});

		});
	</script>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1">
<p>テキストの選択にイベントリスナーを設定する</p>
</section>
</body>
</html>

実行すると、次のように選択したテキストのみを出力して確認することができます。

選択したテキストをそのまま出力する

selectstartの中でイベントmouseupのイベントリスナーを登録しているのは、テキストの選択開始と選択完了をセットにするためです。

選択したテキストを取得して出力する処理はmouseupの中に記述しています。
JavaScriptでは選択範囲を扱うSelectionオブジェクトが元々用意されており、このオブジェクトのgetSelectionメソッドを使って選択範囲を、文字列形式で取得するためにtoStringメソッドを使って取得します。

選択範囲の開始位置と選択終了位置を取得する

もし選択した文字列をそのまま取得するのではなく、開始位置と終了位置を取得したいときは、anchorOffsetプロパティfocusOffsetプロパティを参照します。
これらのプロパティはテキストの1文字目を0として、そこからの距離(文字数)を知ることができます。

コード例

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>GRAYCODE JavaScript</title>
	<script>
		window.addEventListener('DOMContentLoaded', function(){
			
			var p_element = document.querySelector("p");

			p_element.addEventListener('selectstart', function(){
				p_element.addEventListener('mouseup', function(event) {
					console.log("選択開始位置:" + window.getSelection().anchorOffset);
					console.log("選択終了位置:" + window.getSelection().focusOffset);
				});
			});

		});
	</script>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1">
<p>テキストの選択にイベントリスナーを設定する</p>
</section>
</body>
</html>
選択の開始位置と終了位置を出力

タッチ操作したときに選択範囲を取得する

これまではマウス操作を中心としてきましたが、スマホやタブレットなどのタッチ操作に対応した端末ではmouseupではなくtouchendを使用します。

コード例

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>GRAYCODE JavaScript</title>
	<script>
		window.addEventListener('DOMContentLoaded', function(){
			
			var p_element = document.querySelector("p");

			p_element.addEventListener('selectstart', function(){
				p_element.addEventListener('touchend', function(event) {
					alert(window.getSelection().toString());
				});
			});

		});
	</script>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1">
<p>テキストの選択にイベントリスナーを設定する</p>
</section>
</body>
</html>

以下はiPhoneのChromeで開いてテキストを選択したときの表示例です。

タッチ操作で選択したテキストを表示

フォームの各要素でテキストを選択した場合

input要素textarea要素にあるテキストを選択したときは、イベントselectstartの代わりにselectが発生します。

次の例ではinput要素value属性のテキストを選択したときに、選択したテキストをそのままconsole.logメソッドで出力します。

コード例

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>GRAYCODE JavaScript</title>
	<script>
		window.addEventListener('DOMContentLoaded', function(){

			document.querySelector("input").addEventListener('select', function(){
				console.log(window.getSelection().toString());
			});
		});
	</script>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1">
<input type="text" value="インプット要素内のテキストを選択する">
</section>
</body>
</html>

フォームの要素については、イベントリスナーを入れ子にすることなく選択範囲を取得することができます。
実行してみると、次のように選択したテキストが出力されます。

input要素のテキストを選択すると、選択したテキストが出力される

選択した開始位置と終了位置を取得したい場合については、selectionStartプロパティselectionEndプロパティを参照します。

コード例

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>GRAYCODE JavaScript</title>
	<script>
		window.addEventListener('DOMContentLoaded', function(){

			document.querySelector("input").addEventListener('select', function(){
				console.log("選択開始位置:" + event.target.selectionStart);
				console.log("選択終了位置:" + (event.target.selectionEnd -1));
			});
		});
	</script>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1">
<input type="text" value="インプット要素内のテキストを選択する">
</section>
</body>
</html>

開始位置は先頭の文字を0とした文字数となりますが、終了位置は先頭からの文字数+1(次の文字位置)を返すため注意が必要です。
上のコードではselectionEndプロパティから-1をすることで、開始位置と同様に先頭の文字からの文字数を取得しています。

こちらの記事は役に立ちましたか?

ありがとうございます。
もしよろしければ、あわせてフィードバックや要望などをご入力ください。

コメントありがとうございます!
運営の参考にさせていただきます。