ホイール系イベント2014年版クロスブラウザ

Updated / Published

ホイール系のイベントは各ブラウザの実装がバラバラでクロスブラウザ対策に苦労するイベントのひとつとして知られているでしょうが、Document Object Model Level 3 Eventsにより標準化されたwheelイベントが多くのブラウザで実装されてきています。本エントリーでは現状のホイール操作時の各イベントについて、クロスブラウザでフォールバックしながら用いる方法を解説していきます。

ホイール系イベント比較

DOMMouseScroll, MozMousePixelScroll

DOMMouseScrollイベントとMozMousePixelScrollイベントはどちらもGecko 固有のため、現存ではFirefoxしかサポートしていないイベントです。DOMMouseScrollはスクロールする行数を、MozMousePixelScrollはスクロールするピクセル数を表します。

これらのイベントからスクロール量を取得するには、detailプロパティを用います。detailプロパティの値が正の数なら下方向へのスクロール、負の数なら上方向へスクロールしていることを示します。もうひとつaxisプロパティというのがありますが、ここでは割愛します。

mousewheel

mousewheelイベントはInternet Explorer 6が最初に実装したイベントで、その後Firefoxを除く主要ブラウザですべて実装されているイベントです。つまり、Firefox以外がサポートしているイベントですが、実装は各ブラウザにより違いがあります。

mousewheelイベントからホイールの回転量を取得するには、wheelDeltaプロパティを用います。wheelDeltaプロパティの値が正の数なら奥へホイール、負の数なら手前へホーイルさせていることを示します。他にもwheelDeltaXプロパティ、wheelDeltaYプロパティ 、detailプロパティがありますが、これらのプロパティは各ブラウザによってサポートの有無があるためここでは割愛します。

wheel

wheelイベントはDocument Object Model Level 3 Eventsにより標準化されたイベントで、サポート状況は以下の通りです。

IE
IE9よりサポート
Chrome
Chrome31よりサポート
Firefox
Firefox17よりサポート
Safari
Safari8(Mac OS X 10.10 Yosemite または iOS8)よりサポート
Opera
Opera18よりサポート

SafariはSafari8からとごく最近サポートしたことになる以上の状況から、もはや現状ではwheelイベントを中心にSafari7以下とIE8以下へのフォールバックのためにmousewheelイベントを用いれば良いということになります。加えてFirefox 16以下もサポートするかどうかの必要に応じてDOMMouseScrollイベントもしくはMozMousePixelScrollイベントも併せてフォールバックに用いることになります。

wheelイベントから上下のスクロール量を取得するには、deltaYプロパティを用います。 deltaY プロパティの値が正の数なら下へ、負の数なら上へスクロールさせていることを示します。他にもdeltaXプロパティ、deltaZプロパティがありますが、ここでは割愛します。

クロスブラウザでのイベント設定例

jQueryを用いた場合

var mousewheelevent = 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll';
$(document).on(mousewheelevent,function(e){
	var delta = e.originalEvent.deltaY ? -(e.originalEvent.deltaY) : e.originalEvent.wheelDelta ? e.originalEvent.wheelDelta : -(e.originalEvent.detail);
	if (delta < 0){
		e.preventDefault();
		//下にスクロールした場合の処理
	} else if (delta > 0){
		e.preventDefault();
		//上にスクロールした場合の処理
	}
});

jQueryを用いた場合の各プロパティにアクセスするには、originalEventオブジェクトを経由する必要があります。イベントによって正の数、負の数の返り値がバラバラなので統一しておくと良いでしょう。ここではwheelイベントとDOMMouseScrollイベントの場合の返り値にマイナスをつけて統一しています。

ネイティブJavaScriptの場合

var mousewheelevent = 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll';
try{
	document.addEventListener (mousewheelevent, onWheel, false);
}catch(e){
	//for legacy IE
	document.attachEvent ("onmousewheel", onWheel);
}
function onWheel(e) {
	if(!e) e = window.event; //for legacy IE
	var delta = e.deltaY ? -(e.deltaY) : e.wheelDelta ? e.wheelDelta : -(e.detail);
	if (delta < 0){
		e.preventDefault();
		//下にスクロールした場合の処理
	} else if (delta > 0){
		e.preventDefault();
		//上にスクロールした場合の処理
	}
}

なお、e.preventDefault();はイベントに応じて実際に処理をする場合にのみ返すようにしましょう。これは、MacのMagic Mouseやトラックパッドのように左右のホイール操作がページ移動機能に割り当てられているPCも存在するためです。e.preventDefault();を返してしまうと、デフォルトでバンドルされている機能が動作しなくなることに注意してください。