[解決済み] ブラウザ間のマウスホイール速度の正規化
質問
対象 別の質問 を構成しました。 この回答 を含む。 このサンプルコード .
このコードでは、HTML5 Canvas のズームイン/アウトにマウスホイールを使用しています。Chrome と Firefox の速度差を正規化するコードをいくつか見つけました。しかし、Safari のズーム処理は、これらのいずれよりもずっとずっと高速です。
現在、私が持っているコードは以下の通りです。
var handleScroll = function(e){
var delta = e.wheelDelta ? e.wheelDelta/40 : e.detail ? -e.detail/3 : 0;
if (delta) ...
return e.preventDefault() && false;
};
canvas.addEventListener('DOMMouseScroll',handleScroll,false); // For Firefox
canvas.addEventListener('mousewheel',handleScroll,false); // Everyone else
Chrome v10/11, Firefox v4, Safari v5, Opera v11, IE9で、同じ量のマウスホイール回転で同じ「デルタ」値を得るには、どんなコードを使えばよいでしょうか。
この質問 は関連するが、良い答えがない。
編集 : さらに調査したところ、1つのスクロールイベント「上」は
| evt.wheelDelta | evt.detail ------------------+----------------+------------ サファリ v5/Win7|120|0 サファリ v5/OS X|120|0 サファリ v7/OS X|12|0 クローム v11/Win7|120|0 クローム v37/Win7|120|0 Chrome v11/OS X|3(!)|0(間違っている可能性あり) クローム v37/OS X|120|0 IE9/Win7|120|未定義 オペラ v11/OS X|40|-1 オペラ v24/OS X|120|0 オペラv11/Win7|120|-3 Firefox v4/Win7|未定|-3 Firefox v4/OS X|未定義|-1 Firefox v30/OS X|未定|-1
さらに、MacBookのトラックパッドをOS Xで使用すると、ゆっくり動いても異なる結果が得られます。
-
SafariとChromeでは
wheelDelta
は、マウスホイールの値が120ではなく、3になっています。 -
Firefoxでは
detail
は通常2
は、時々1
しかし、非常にゆっくりスクロールした場合 イベントハンドラが全く起動しない .
そこで質問です。
この動作を区別する最善の方法は何でしょうか(ユーザーエージェントやOSのスニッフィングがないのが理想です)。
解決方法は?
2014年9月編集
それを考えると
- OS X上の同じブラウザの異なるバージョンで過去に異なる値が得られ、また将来もそうなる可能性があり、また
- OS Xでトラックパッドを使用すると、非常に似た結果が得られます。 効果 はマウスホイールと同じですが、イベント内容は大きく異なります。 値 そして、そのデバイスの違いをJSで検出することはできません。
...私は、このシンプルで符号ベースのカウントコードを使用することをお勧めします。
var handleScroll = function(evt){
if (!evt) evt = event;
var direction = (evt.detail<0 || evt.wheelDelta>0) ? 1 : -1;
// Use the value as you will
};
someEl.addEventListener('DOMMouseScroll',handleScroll,false); // for Firefox
someEl.addEventListener('mousewheel', handleScroll,false); // for everyone else
オリジナルの試みは以下の通りです。
ここで、値を正規化するスクリプトに初めて挑戦してみました。OS Xでは2つの欠点があります。OS XのFirefoxは、あるべき値の1/3の値を生成し、OS XのChromeは、あるべき値の1/40の値を生成します。
// Returns +1 for a single wheel roll 'up', -1 for a single roll 'down'
var wheelDistance = function(evt){
if (!evt) evt = event;
var w=evt.wheelDelta, d=evt.detail;
if (d){
if (w) return w/d/40*d>0?1:-1; // Opera
else return -d/3; // Firefox; TODO: do not /3 for OS X
} else return w/120; // IE/Safari/Chrome TODO: /3 for Chrome OS X
};
このコードを自分のブラウザで試すには、こちらをご覧ください。 http://phrogz.net/JS/wheeldelta.html
OS X上のFirefoxとChromeでの検出と動作改善の提案を歓迎します。
編集
: Tom からの提案のひとつは、各イベントの呼び出しを単純にひとつの動きとしてカウントし、距離の符号を使って調整することです。この方法は、OS X のスムーズ/アクセラレーションスクロールでは良い結果を得られませんし、マウスホイールを非常に速く動かした場合 (例.
wheelDelta
が240の場合)しかし、このようなことはめったにありません。このコードは、そこに書かれている理由から、現在ではこの回答の一番上に示されている推奨テクニックとなっています。
関連
-
vueネットワークリクエストソリューション ネイティブネットワークリクエストとjsネットワークリクエストライブラリ
-
Vueの要素ツリーコントロールに破線を追加する説明
-
Vue+ElementUIによる大規模なフォームの処理例
-
元のイベントが実行されなかった後に要素を追加するためのjQueryソリューション
-
vueのプロジェクトでモックを使用する方法を知っていますか?
-
[解決済み】awaitは非同期関数でのみ有効です。
-
[解決済み】gulp anythingを実行するたびに、アサーションエラーが発生します。- タスク関数を指定する必要があります
-
JavaScriptのStringに関する共通メソッド
-
フロントエンド null のプロパティ 'disabled' を読み取れない 問題が解決された
-
Uncaught TypeError: null のプロパティ 'offsetHeight' を読み取れませんでした。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
JSクロスドメインソリューション リアクト構成 リバースプロキシ
-
vue+webrtc(Tencent cloud)ライブ機能の実践を実現するために
-
VUEグローバルフィルターの概念と留意点、基本的な使い方
-
Vueでルートネスティングを実装する例
-
[解決済み】ERROR エラーです。スイッチのname属性が指定されていないフォームコントロールの値アクセッサがない
-
[解決済み】(Google Map API) Geocodeは以下の理由で成功しませんでした。REQUEST_DENIED
-
nodejs unhandledPromiseRejectionWarning メッセージ
-
HTML5 LocalStorage ローカルストレージとセッションストレージの使用法
-
モジュールのビルドに失敗しました。Error: ENOENT: no such file or directory, scandir 'D:\.... \node_modules
-
[解決済み] 内部要素のスクロール位置が上/下に達したときに親要素のスクロールを防止しますか?