🖱️

HTMLの<input type="number">フィールドにおけるマウスホイール動作の無効化

2023/11/27に公開

背景

HTMLにおいて <input type="number"> は、数値入力を容易にするためのフォームフィールドです。ユーザーはテキスト入力に加えて、マウスホイールやキーボードの矢印キーを使用して値を調整できます。これは便利な機能ですが、一部の状況では意図しない挙動を引き起こす可能性があります。

RailsでUIを作るときには、本当は number_fieldにしたかったところをわざわざ、text_filedにして実装していました。

number fieldの例

問題

<input type="number"> フィールド上にマウスカーソルがあるときに、ホイールを上下すると画面が上下しつつ、 フィールドの値も変わってしまいます

この問題はかなり昔からあって、5年前ぐらいからはWebKitに存在していると思います。

アプローチ

半ば諦めていたのですが、そもそもJavaScriptでホイールを無効化してしまえば解決できると思ってコードを書きました。
これにより、マウスホイール操作による数値の変更を防ぎつつ、ページのスクロールはそのままにできます。

実装

ESのモジュールにしておきました。

以下のコードスニペットは、<input type="number"> フィールドでのマウスホイールによる値変更を阻止する方法を示しています。

/**
 * Disable changing value using mouse wheel
 */
export function disableWheel(selector) {
  document.querySelectorAll(selector).forEach(input => {
    input.addEventListener('wheel', event => event.preventDefault(), { passive: false });
  });
}

この関数は、指定されたセレクタに一致する全ての要素にイベントリスナーを追加します。wheel イベントが発生した際に preventDefault メソッドを呼び出すことで、マウスホイールによる値の変更を阻止します。

呼び出し方は以下の通りです。

import { disableWheel } from './disable-wheel.js';

window.addEventListener('load', function () {
  disableWheel('input[type="number"]')
}, false);

こちらにも置いておきます。
https://gist.github.com/matsubo/537aaecfbfd5389794da22f273afa01b

考察

この実装は、特定の要素に対するユーザーインタラクションの制御において非常に効果的です。しかし、すべての <input type="number"> フィールドでこの挙動を無効化することは、ユーザーにとって予期せぬ経験をもたらすことがあります。したがって、この機能を適用する際は、ユーザビリティとのバランスを考慮することが重要です。また、将来的にブラウザのデフォルト挙動が変更される可能性も考慮し、継続的なメンテナンスとテストが必要となります。

株式会社マインディア テックブログ

Discussion