JavaScript

最終更新日:
公開日:

レシピ

イベント

スワイプ/フリックしたときに処理を実行する

スマホやタブレットなどのタッチ操作に対応した端末で、スワイプ/フリック操作があったときに指定した処理を実行する方法について解説します。

この記事のポイント

  • イベントtouchmoveを使ってタッチポイントの座標を取得する
  • スワイプ/フリックの開始位置と終了位置を比較すると向きが分かる

目次

スワイプ/フリックを検知する

デモページはこちら
※スマホ/タブレットなどタッチ操作に対応した端末か、またはブラウザの端末シミュレーターを使って青いエリアをスワイプしてみてください。

ページでスワイプ/フリックがあると次の3つのイベントが発生します。

イベント名発生するタイミング
touchmoveスワイプ/フリックしているとき
touchstartタッチしたとき
touchend指が離れたとき

スワイプ/フリックしたときに発生するイベントはtouchmoveです。
それ以外のtouchstarttouchendはスワイプ/フリックに限らずスクリーンにタッチすると発生するイベントですが、スワイプ/フリックしたときも発生するイベントです。

touchmoveはマウスカーソルの移動で発生するイベントmousemoveと非常によく似ており、同じ要領で使うことができます。
以下のコードはスワイプ/フリックしたときにタッチされた座標を出力するコードです。

コード例

<!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('load', function(){

			// スワイプ/フリック
			document.getElementById("content1").addEventListener('touchmove', logTouch);
		});

		function logTouch(event) {
			console.log("X:" + event.touches[0].pageX);
			console.log("Y:" + event.touches[0].pageY);
		}
	</script>
	<style>
	#content1 {
		padding: 20px;
		height: 300px;
		background-color: #3f98d1;
	}
	</style>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1"></section>
</body>
</html>

ブラウザで実行すると、スワイプ/フリックの動きに応じてタッチポイントの座標が出力されます。

スワイプ/フリックすると...
タッチポイントの座標を出力する

スワイプ/フリックされた向きを判定する

スワイプ/フリックしたときの座標と、touchstarttouchendの2つのイベントを使って、スワイプ/フリックされた向きを判定することができます。
まずは左右の向きを取得してみましょう。

コード例

<!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>
		var startX = null;
		var endX = null;

		window.addEventListener('load', function(){

			// スワイプ/フリック
			document.getElementById("content1").addEventListener('touchmove', logSwipe);

			// タッチ開始
			document.getElementById("content1").addEventListener('touchstart', logSwipeStart);

			// タッチ終了
			document.getElementById("content1").addEventListener('touchend', logSwipeEnd);
		});

		function logSwipeStart(event) {
			event.preventDefault();

			startX = event.touches[0].pageX;
		}

		function logSwipe(event) {
			event.preventDefault();

			endX = event.touches[0].pageX;
		}

		function logSwipeEnd(event) {
			event.preventDefault();

			if( 0 < (endX - startX) ) {
				console.log("右向き");
			} else {
				console.log("左向き");
			}
		}
	</script>
	<style>
	#content1 {
		padding: 20px;
		height: 300px;
		background-color: #3f98d1;
	}
	</style>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1"></section>
</body>
</html>

以下、コードを順に解説していきます。

冒頭の2つの変数startXendXはタッチポイントの開始位置と終了位置をそれぞれ代入するために宣言しておきます。

続く以下のコードでは、ページが読み込まれたタイミングでスワイプ/フリックしたときのイベントtouchmove、タッチを開始したときのイベントtouchstart、そしてタッチ(スワイプ/フリック)が終了したときのイベントtouchendをそれぞれイベントリスナーに登録しています。
これでスワイプ/フリックがあったときに、それぞれ指定したメソッドが実行されます。

イベントリスナーの登録

window.addEventListener('load', function(){

	// スワイプ/フリック
	document.getElementById("content1").addEventListener('touchmove', logSwipe);

	// タッチ開始
	document.getElementById("content1").addEventListener('touchstart', logSwipeStart);

	// タッチ終了
	document.getElementById("content1").addEventListener('touchend', logSwipeEnd);
});

logSwipeStartメソッドはスワイプ/フリックを開始した時点のタッチポイント座標を変数startXに代入します。

logSwipeStartメソッド

function logSwipeStart(event) {
	event.preventDefault();

	startX = event.touches[0].pageX;
}

また、メソッドにあるevent.preventDefault();はタッチ操作のデフォルト操作をキャンセルするために指定します。
スワイプ中に、タッチされたことによる処理が実行されて中断することの内容に実行します。
このメソッドは他2つのlogSwipeメソッドlogSwipeEndでも実行します。

続くlogSwipeメソッドでは、スワイプ/フリック中のタッチポイント座標を変数endXに代入します。
イベントtouchmoveはスワイプ/フリック中に何度も呼び出されるため、スワイプ/フリック終了まで最新のタッチポイント座標を代入し続けます。

logSwipeメソッド

function logSwipe(event) {
	event.preventDefault();

	endX = event.touches[0].pageX;
}

3つ目のlogSwipeEndメソッドはスワイプ/フリックが終了したタイミングに実行され、2つの変数を比較して向きを判定します。
if文の条件式でendX – startXで値をチェックし、正の値ならX軸で右側に動いているため右向き、負の値ならX軸で左側に動いているため左向きと出力します。

logSwipeメソッド

function logSwipeEnd(event) {
	event.preventDefault();

	if( 0 < (endX - startX) ) {
		console.log("右向き");
	} else {
		console.log("左向き");
	}
}

ブラウザで実行すると、スワイプ/フリックの動きに応じて次のように出力されます。

右方向にスワイプ/フリック

続いて、反対方向にスワイプ/フリックしてみたときの出力です。

反対方向にスワイプ/フリック

今回の例ではX軸を使って左右方向の判定をしていますが、Y軸を使うことで上下方向の判定をすることも可能です。

コード例

<!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>
		var startY = null;
		var endY = null;

		window.addEventListener('load', function(){

			// スワイプ/フリック
			document.getElementById("content1").addEventListener('touchmove', logSwipe);

			// タッチ開始
			document.getElementById("content1").addEventListener('touchstart', logSwipeStart);

			// タッチ終了
			document.getElementById("content1").addEventListener('touchend', logSwipeEnd);
		});

    function logSwipeStart(event) {
			event.preventDefault();

			startY = event.touches[0].pageY;
    }

		function logSwipe(event) {
			event.preventDefault();

			endY = event.touches[0].pageY;
		}

		function logSwipeEnd(event) {
			event.preventDefault();

			if( 0 < (endY - startY) ) {
				console.log("下向き");
			} else {
			 	console.log("上向き");
			}
		}
	</script>
	<style>
	#content1 {
		padding: 20px;
		height: 300px;
		background-color: #3f98d1;
	}
	</style>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1"></section>
</body>
</html>

コードの赤字が変更箇所です。
基本的には向きの判定をX軸からY軸に変更しているのみですが、logSwipeEndメソッドのif文でendY – startYの計算をしたときに正の値であれば「下向き」、負の値であれば「上向き」と出力します。

ブラウザで実行すると、スワイプ/フリックの動きに応じて次のように出力されます。

上方向にスワイプ/フリック

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

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

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