ホイール系イベント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();
を返してしまうと、デフォルトでバンドルされている機能が動作しなくなることに注意してください。