カテゴリー
JavaScript

マウスイベント

マウスに関連したイベントはたくさんある。

click contextmenu dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave

マウスイベントはすべてバブリングする。

ただし、mouseenter、mouseleaveは例外 リンクに対するclickイベントと、Submitボタンはデフォルトの動作を持つ。

この動作は抑止できる。

contextmenuイベントをキャンセルすれば、コンテキストメニューが表示されないようにもできる。

マウスイベントハンドラに渡されるイベントオブジェクト

clientXプロパティ clientYプロパティ altKey、ctrlKey、metaKey、ShiftKeyプロパティ buttonプロパティ

drag()関数 mousedownイベントハンドラから呼び出され、絶対位置指定したドキュメント要素をユーザがドラッグできるようにする。

DOMイベントモデルでも、IEイベントモデルでも動作する。

ドキュメント要素をドラッグする

/*
*Drag.js:絶対位置指定されたHTML要素をドラッグする
*
*このモジュールはdrag()関数を定義する
*イベントハンドラから呼び出される。
*この後のmousemoveイベントで、指定された要素を移動する
*mouseupイベントでドラッグをやめる
*この実装は、標準イベントモデルでも、IEイベントイベントモデルでも動作する
*例15-8のgetScrollOffsets()関数を必要とする
*
*引数:
* elementToDrag:mousedownイベントが発生した要素か、
*	その要素を包含する要素。
*	この要素は絶対位置指定していなければならない
*	style.leftとstyle.topの値が、ユーザのドラッグに応じて変更される
* event: mousedownイベントのEventオブジェクト
*/
function drag(elementToDrag, event) {
	//マウスの初期位置。ドキュメント座標に変換される
	var scroll = getScrollOffsets();	//例 15-8で定義されているユーティリティ関数
	var startX = event.clientX + scroll.x;
	var startY = event.clientY + scroll.y;

	//ドラッグされる要素の初期位置(ドキュメント座標)
	//elementToDragは絶対位置指定されるので、offsetParentがドキュメントボディと想定している
	var origX = elementToDrag.offsetLeft;
	var origY = elementToDrag.offsetTop;

	//mousedownイベントと要素の左上角の距離を計算する
	//マウスが移動している間、この距離が維持されるようにする
	var deltaX = startX - origX;
	var deltaY = startY - origY;

	//mousemoveイベントとmouseupイベント用のイベントハンドラを登録する
	if (document.addEventListener) {	//標準イベントモデル
		//キャプチャリングイベントハンドラをドキュメントに登録する
		document.addEventListener("mousemove", moveHandler, true);
		document.addEventListener("mouseup", upHandler, true);

	} else if(document.attachEvent) {	//IE5~8用のIEイベントモデル
		//IEイベントモデルでは、イベントをキャプチャしたい要素に対して
		//setCapture()を呼び出すことで、イベントをキャプチャする
		elementToDrag.setCapture();
		elementToDrag.attachEvent("onmousemove", moveHandler);
		elementToDrag.attachEvent("onmouseup", upHandler);
		//マウスキャプチャを失った場合は、mouseupとして処理する
		elementToDrag.attachEvent("onlosecapture", upHandler);
	}

	//このイベントは処理が完了したので、ほかの要素が処理しないようにする
	if (event.stopPropagetion) event.stopPropagetion();	//標準モデル
	else event.cancelBubble = true;	//IE

	//デフォルトの動作を抑止する
	if (event.preventDefault) event.preventDefault();	//標準モデル
	else event.returnValue = false;	//IE

	//要素がドラッグされている間、mosemoveイベントをキャプチャする
	//ハンドラ。要素の移動処理を行う
	function moveHandler(e) {
		if (!e) e = window.event;	//IEイベントモデル

		//要素を現在のマウス位置まで移動する
		//スクロールバーの位置や、
		//最初のマウスクリック時のオフセットを計算に入れて調整する必要がある
		var scroll = getScrollOffsets();
		elementToDrag.style.left = (e.clientX + scroll.x - deltaX) + "px";
		elementToDrag.style.top = (e.clientY + scroll.y - deltaY) + "px";

		//このイベントをほかの場所で処理されないようにする
		if (e.stopPropagetion) e.stopPropagetion();
		else e.cancelBubble = true;
	}

	//ドラッグの最後で発生するmouseupイベントをキャプチャするハンドラ
	function upHandler(e) {
		if (!e) e = window.event;	//IEイベントモデル

		//キャプチャリングイベントハンドラを登録解除する
		if (document.removeEventListener) {	//DOMイベントモデル
			document.removeEventListener("onmouseup", upHandler, true);
			document.removeEventListener("onmousemove", moveHandler, true);
		} else if (document.detachEvent) {	//IE5以降のイベントモデル
			elementToDrag.detachEvent("onlosecapture", upHandler);
			elementToDrag.detachEvent("onmouseup", upHandler);
			elementToDrag.detachEvent("onmousemove", moveHandler);
			elementToDrag.releaseCapture();
		}

		//これ以上、イベントを伝播しないようにする
		if (e.stopPropagetion) e.stopPropagetion();	//標準モデル
		else e.cancelBubble = true;	//IE
	}
}

ウィンドウのスクロールバーの位置を取得する

// 現在のスクロールバーの位置を、オブジェクトのx,yプロパティに格納して返す
function getScrollOffsets(w) {
	//指定したウィンドウ(引数なしの場合は現在のウィンドウ)を使う
	w = w || window;

	//以下は、すべてのブラウザ(IE8以前を除く)で動作する
	if (w.pageXOffset != null) return {x: w.pageXOffset, y:w.pageYOffset};

	//標準モードのIE用(任意のブラウザ用)
	var d = w.document;
	if (document.compatMode == "CSS1Compat")
		return {x:d.documentElement.scrollLeft, y:d.documentElement.scrollTop};

	//クァークスモードのブラウザ用
	return {x: d.body.scrollLeft, y: d.body.scrollTop };
}

参考書籍:

オライリー JavaScript 第6版

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です