The 'mouseup' event is fired the moment a user releases a previously pressed mouse button.
「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
を使うことで、イベントハンドラを柔軟に追加したり、削除したりすることも簡単です。
これらを併用することで、ドラッグ操作の開始・終了を検知したり、描画操作(お絵かきツールなど)で線を引き始めるタイミングと終わるタイミングを捉えたりできます。
mousedown
→ mouseup
が同じ要素で発生した場合に呼び出されるclick
イベントは、実際にユーザーが「クリック」したことを示します。ですが、ユーザーがボタンを押し、ドラッグした後に別の場所でボタンを離した場合、click
は発生しません。一方、mouseup
は要素上でボタンを離したら必ず発生します(ただし、要素上にマウスが乗っている必要があります)。
ドラッグアンドドロップの実装では、通常 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
プロパティを使ってどのマウスボタンが離されたか判断し、メッセージを表示しています。
「ドラッグアンドドロップ」は、以下のような流れで実装されることが多いです。
mousedown
でドラッグ開始判定・初期設定mousemove
で要素の位置を更新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>
mouseup
をドキュメント全体(document
)に登録することで、マウスが要素外へ移動してもマウスボタンが離されたタイミングを逃さずに取得できます。isDragging
フラグを使って、ドラッグ中かどうかを判定し、ドラッグ終了でフラグを解除します。canvas要素を用いたシンプルな「お絵かき」機能の例です。
mousedown
:描画開始(描画フラグをtrueに)mousemove
:描画フラグがtrueの間だけ線を引くmouseup
:描画終了(描画フラグをfalseに)ここでも、mouseup
が描画終了タイミングとして重要です。
mouseup
イベントで受け取れるイベントオブジェクト(MouseEvent)には、多くの情報が含まれています。
また、バブリングやキャプチャリングに関する制御も可能です。詳しくは次の「イベント伝播と高度な話題」で解説します。
JavaScriptのイベント伝播には、キャプチャリングフェーズとバブリングフェーズがあります。
document
)から目的の要素に向かってイベントが伝播するaddEventListener
の第3引数またはオプションでcapture: true
を指定すると、キャプチャリングフェーズでイベントを受け取ることができます。通常はバブリングフェーズで受け取ります。
JavaScript
element.addEventListener("mouseup", handler, { capture: true });
こうすると、要素の子孫より先にイベントを受け取れるため、ネストした要素全体の制御が必要なケースやイベントの取り消しが必要な場合などで役立ちます。
例:右クリックメニューを独自のコンテキストメニューに差し替えたい場合、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
)に対して登録すると、イベントを逃さず取得できます。ただし、大量のイベントを捌くことになるので、可能な範囲で最適化するとよいでしょう。
event.stopPropagation()
や event.preventDefault()
をどこかで呼び出していないかmousedown
→ mouseup
→ click
の順序を理解しようmousemove
やmouseup
を受け取れるよう、document
にリスナーを付与するaddEventListener
やremoveEventListener
がサポートされていないケースがある(attachEvent
, detachEvent
が必要)mousedown
(開始) → mousemove
(移動) → mouseup
(終了)、あるいはclick
。event.button
や座標プロパティ、修飾キーなどを使用すると高度な制御が可能。JavaScriptにおけるマウスイベントはUI操作の基盤となるため、「mouseup」以外にも「mousedown」「click」「mousemove」「mouseenter」「mouseleave」「contextmenu」などと合わせて理解することが大切です。応用範囲は広いので、まずは基本的なサンプルを動かしてみて、徐々に複雑なケースへとステップアップしていきましょう。