JavaScript

The 'mouseup' event is fired the moment a user releases a previously pressed mouse button.

mouseup [event]

「mouseup」イベントとは

「mouseup」イベントは、ユーザーがマウスのボタンを押し、押していたボタンを離したとき(マウスボタンを"アップ"したとき)に発生するイベントです。たとえば、左クリックや右クリック、または中クリックのホイールボタンを離した瞬間に反応します。

mousedown
ボタンを押したタイミング
mouseup
押したボタンを離したタイミング
click
mousedownからmouseupまでが同じ要素で行われた場合に発生

「mouseup」は、クリック動作の後半で発生するイベントであり、DOM操作やドラッグアンドドロップの終了処理などに活用できます。

基本的な使い方

イベントの付与方法

マウスイベントは、通常以下のような方法で要素にイベントリスナーを登録して扱います。

HTMLタグに直接指定する方法(推奨されない場合が多い)

HTML

<button onmouseup="handleMouseUp()">ボタン</button>

<script>
	function handleMouseUp() {
		console.log("マウスボタンが離されました。");
	}
</script>

HTML内に直接イベントハンドラを埋め込む方法です。小規模なスクリプトでは簡単ですが、コードの可読性が下がる、スクリプトがHTMLに混在するなどの理由から大規模開発にはあまり推奨されません。

JavaScriptでイベントリスナーを登録する方法(推奨)

HTML

<button id="myButton">ボタン</button>

<script>
	const button = document.getElementById("myButton");
	button.addEventListener("mouseup", function(event) {
		console.log("マウスボタンが離されました。", event);
	});
</script>

こちらの方法は、HTMLとJavaScriptを分離しやすく、メンテナンス性や拡張性に優れています。

addEventListenerを使うことで、イベントハンドラを柔軟に追加したり、削除したりすることも簡単です。

「mouseup」と他のマウスイベントとの違い

mousedownとの違い

mousedown
ユーザーがマウスボタンを押し下げた直後
mouseup
押されたボタンが離された直後

これらを併用することで、ドラッグ操作の開始・終了を検知したり、描画操作(お絵かきツールなど)で線を引き始めるタイミングと終わるタイミングを捉えたりできます。

clickとの違い

click
通常、mousedownmouseup が同じ要素で発生した場合に呼び出される
mouseup
要素上でボタンを離した瞬間(要素上からmousedragして他の要素上でボタンを離すと呼び出されないこともある)

clickイベントは、実際にユーザーが「クリック」したことを示します。ですが、ユーザーがボタンを押し、ドラッグした後に別の場所でボタンを離した場合、clickは発生しません。一方、mouseupは要素上でボタンを離したら必ず発生します(ただし、要素上にマウスが乗っている必要があります)。

mousemoveとの違い

mousemove
マウスカーソルが要素上で動いている間、継続的に呼び出される
mouseup
押下していたボタンが上がった瞬間に1回だけ呼び出される

ドラッグアンドドロップの実装では、通常 mousedown でドラッグを開始し、mousemoveで移動を検知し、mouseupでドラッグの終了処理を行う、という手法が一般的です。

基本的なコード例

シンプルな例

以下は、ユーザーがボタンをクリックして離した瞬間にメッセージを表示する例です。

HTML

<button id="myButton">クリックして離す</button>

<script>
	const button = document.getElementById("myButton");

	button.addEventListener("mouseup", function(event) {
		// イベントオブジェクトでボタンの種類を確認(0:左, 1:中, 2:右)
		const buttonType = event.button;
		let message = "";

		switch(buttonType) {
			case 0:
				message = "左ボタンが離されました。";
				break;
			case 1:
				message = "中ボタン(ホイール)が離されました。";
				break;
			case 2:
				message = "右ボタンが離されました。";
				break;
			default:
				message = "不明なボタンが離されました。";
		}

		console.log(message);
		alert(message);
	});
</script>

上記の例では、event.buttonプロパティを使ってどのマウスボタンが離されたか判断し、メッセージを表示しています。

応用例と実践的な活用シーン

ドラッグアンドドロップ操作

「ドラッグアンドドロップ」は、以下のような流れで実装されることが多いです。

  1. mousedownでドラッグ開始判定・初期設定
  2. mousemoveで要素の位置を更新
  3. mouseupでドラッグの終了処理
ドラッグできます

HTML

<div id="draggable">ドラッグできます</div>

<script>
	const box = document.getElementById("draggable");
	let isDragging = false;
	let offsetX, offsetY;

	box.addEventListener("mousedown", (event) => {
		isDragging = true;
		// 要素の左上とマウスの座標の差分を保存
		offsetX = event.clientX - box.offsetLeft;
		offsetY = event.clientY - box.offsetTop;
	});

	document.addEventListener("mousemove", (event) => {
		if (isDragging) {
			box.style.left = (event.clientX - offsetX) + "px";
			box.style.top = (event.clientY - offsetY) + "px";
		}
	});

	document.addEventListener("mouseup", (event) => {
		if (isDragging) {
			isDragging = false;
			console.log("ドラッグ終了");
		}
	});
</script>

お絵かきツール

canvas要素を用いたシンプルな「お絵かき」機能の例です。

  1. mousedown:描画開始(描画フラグをtrueに)
  2. mousemove:描画フラグがtrueの間だけ線を引く
  3. mouseup:描画終了(描画フラグをfalseに)

ここでも、mouseupが描画終了タイミングとして重要です。

イベントオブジェクトの詳細

mouseupイベントで受け取れるイベントオブジェクト(MouseEvent)には、多くの情報が含まれています。

event.button
どのマウスボタンか(0:左, 1:中, 2:右)
event.clientX, event.clientY
ビューポート(画面)上でのマウス座標
event.screenX, event.screenY
ディスプレイ全体に対するマウス座標
event.altKey, event.ctrlKey, event.shiftKey, event.metaKey
修飾キーの状態
event.target
イベントが発生した要素(もしくはバブリング経路上の要素)
event.type
イベントの種類("mouseup"など)

また、バブリングやキャプチャリングに関する制御も可能です。詳しくは次の「イベント伝播と高度な話題」で解説します。

イベント伝播と高度な話題

キャプチャリングとバブリング

JavaScriptのイベント伝播には、キャプチャリングフェーズとバブリングフェーズがあります。

キャプチャリングフェーズ
最上位のルート(document)から目的の要素に向かってイベントが伝播する
ターゲットフェーズ
実際にイベントが発生した要素が処理を受け取る
バブリングフェーズ
イベントが親要素へ向かって伝播する

addEventListenerの第3引数またはオプションでcapture: trueを指定すると、キャプチャリングフェーズでイベントを受け取ることができます。通常はバブリングフェーズで受け取ります。

JavaScript

element.addEventListener("mouseup", handler, { capture: true });

こうすると、要素の子孫より先にイベントを受け取れるため、ネストした要素全体の制御が必要なケースやイベントの取り消しが必要な場合などで役立ちます。

イベントの停止

event.stopPropagation()
バブリングまたはキャプチャリングを途中で停止する
event.preventDefault()
デフォルト動作(右クリックメニューの表示等)をキャンセルする

例:右クリックメニューを独自のコンテキストメニューに差し替えたい場合、contextmenuイベントやmouseupイベントでevent.preventDefault()を呼び出すことで、ブラウザの標準動作を抑止してカスタムメニューを表示できます。

右クリックしてみてください

HTML

<div id="customArea">
	右クリックしてみてください
</div>

<script>
	const area = document.getElementById("customArea");

	area.addEventListener("mouseup", (event) => {
		// 右クリック(event.button === 2)のときカスタムメニュー表示
		if (event.button === 2) {
			event.preventDefault(); // ブラウザのコンテキストメニューを表示しない
			alert("カスタムコンテキストメニューを表示します(ダイアログで代用)");
		}
	});

	area.addEventListener("contextmenu", (event) => {
		event.preventDefault(); // こちらでも追加の防止処理を
	});
</script>

ベストプラクティスと注意点

イベントの付けすぎに注意

たとえば、複数の要素に対して同じmouseup処理を行いたい場合、一括で親要素またはdocumentに付けてイベントデリゲーションを使う方法があります。多数の要素それぞれにaddEventListenerを行うと、パフォーマンスに影響する場合もあります。

JavaScript

document.body.addEventListener("mouseup", (event) => {
	if (event.target.matches(".myClass")) {
		// クラスが myClass の要素がmouseupされた場合にのみ処理
		console.log("クラスmyClassの要素からのmouseup");
	}
});

タッチデバイスの考慮

スマホやタブレットなど、タッチパネルではマウス操作そのものが存在しないことがあります。タッチイベント(touchstart, touchend, touchmove)と組み合わせて実装するか、ポインターイベント(pointerdown, pointerup, pointermove)で統合的に処理するのが望ましいです。

ドキュメント全体へのリスナー

ドラッグやお絵かきなど、マウスが要素の外へ移動してしまう可能性がある場合は、mouseupをドキュメント全体(document)またはウィンドウ(window)に対して登録すると、イベントを逃さず取得できます。ただし、大量のイベントを捌くことになるので、可能な範囲で最適化するとよいでしょう。

パフォーマンスチューニング

ロジックを最適化
mouseupで重い処理をしない(他のタイミングに処理を分割する)
requestAnimationFrameの活用
アニメーションを伴う処理は、mousemoveやmouseupの都度行うよりも、requestAnimationFrameのコールバック内でまとめて処理するとスムーズになります。

デバッグやトラブルシューティングのポイント

イベントが発火しない
イベントの順序が予期と違う
ドラッグしている最中に動作が途切れる
IEや古いブラウザ対応

まとめ

JavaScriptにおけるマウスイベントはUI操作の基盤となるため、「mouseup」以外にも「mousedown」「click」「mousemove」「mouseenter」「mouseleave」「contextmenu」などと合わせて理解することが大切です。応用範囲は広いので、まずは基本的なサンプルを動かしてみて、徐々に複雑なケースへとステップアップしていきましょう。