web-dev-qa-db-ja.com

`<input type = number>`でのスクロールを無効にします

入力番号フィールドの番号を変更するスクロールホイールを無効にすることは可能ですか? Webkit固有のCSSをいじってスピナーを削除しましたが、この動作を完全に取り除きたいと思います。 iOSでNiceキーボードが表示されるので、type=numberを使用するのが好きです。

96
kjs3

他の人が示唆するような入力番号要素でのマウスホイールイベントのデフォルトの動作を防止します(「blur()」を呼び出すのは、ユーザーが望むものではないため、通常は推奨される方法ではありません)。

しかし。すべてのinput-number要素でmousewheelイベントを常にリッスンするのを避け、要素にフォーカスがあるとき(問題が存在するとき)にのみそれを行います。それ以外の場合ユーザーはページをスクロールできませんマウスポインターがinput-number要素の上にあるとき。

JQueryのソリューション:

// disable mousewheel on a input number field when in focus
// (to prevent Cromium browsers change the value when scrolling)
$('form').on('focus', 'input[type=number]', function (e) {
  $(this).on('mousewheel.disableScroll', function (e) {
    e.preventDefault()
  })
})
$('form').on('blur', 'input[type=number]', function (e) {
  $(this).off('mousewheel.disableScroll')
})

(フォーカスイベントを周囲のフォーム要素に委任します-パフォーマンスに悪い多くのイベントリスナーを回避します。)

76
Grantzau
$(document).on("wheel", "input[type=number]", function (e) {
    $(this).blur();
});
26
stovroz
input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(event){ this.blur() })

http://jsfiddle.net/bQbDm/2/

JQueryの例とクロスブラウザソリューションについては、関連する質問を参照してください。

数値入力スクロールのHTML5イベントリスナー-Chromeのみ

19

すべてを支配する1つのイベントリスナー

これは、純粋なjsでの@Semyon Perepelitsaの回答に似ていますが、ドキュメント要素に1つのイベントリスナーを配置し、フォーカスされた要素が数値入力であるかどうかを確認するため、少し単純です。

document.addEventListener("mousewheel", function(event){
    if(document.activeElement.type === "number"){
        document.activeElement.blur();
    }
});

一部のフィールドで、他のフィールドではないの値のスクロール動作をオフにしたい場合は、代わりに次のようにします。

document.addEventListener("mousewheel", function(event){
    if(document.activeElement.type === "number" &&
       document.activeElement.classList.contains("noscroll"))
    {
        document.activeElement.blur();
    }
});

これとともに:

<input type="number" class="noscroll"/>

入力にnoscrollクラスがある場合、スクロール時に変更されません。そうでない場合、すべてが同じままです。

13
Peter Rakmanyi

@Semyon Perepelitsa

これにはより良い解決策があります。 Blur は入力からフォーカスを削除しますが、これは望ましくない副作用です。代わりにevt.preventDefaultを使用する必要があります。これにより、ユーザーがスクロールしたときの入力のデフォルトの動作が防止されます。コードは次のとおりです。

input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(evt){ evt.preventDefault(); })
13
Dibran

まず、次のいずれかの方法でmousewheelイベントを停止する必要があります。

  1. mousewheel.disableScrollで無効にする
  2. e.preventDefault();でインターセプトする
  3. 要素からフォーカスを削除するel.blur();

最初の2つのアプローチは両方ともウィンドウのスクロールを停止し、最後のアプローチは要素からフォーカスを削除します。どちらも望ましくない結果です。

回避策の1つは、el.blur()を使用し、遅延後に要素の焦点を再設定することです。

$('input[type=number]').on('mousewheel', function(){
  var el = $(this);
  el.blur();
  setTimeout(function(){
    el.focus();
  }, 10);
});
6
James EJ

HTML onwheel 属性を使用するだけです。

このオプションは、ページの他の要素のスクロールには影響しません。

また、後方に動的に作成された入力では機能しないすべての入力のリスナーを追加します。

さらに、CSSを使用して入力矢印を削除できます。

input[type="number"]::-webkit-outer-spin-button, 
input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
input[type="number"] {
    -moz-appearance: textfield;
}
<input type="number" onwheel="this.blur()" />
6
Maikon Matheus

提供された回答は、Firefox(Quantum)では機能しません。イベントリスナーをマウスホイールからホイールに変更する必要があります。

$(':input[type=number]').on('wheel',function(e){ $(this).blur(); });

このコードは、Firefox QuantumおよびChromeで動作します。

2
Mathias Bank

Reactで作業し、解決策を探している人向け。最も簡単な方法は、次のように入力コンポーネントでonWheelCaptureプロップを使用することです。

onWheelCapture={e => { e.target.blur() }}

2
Aleš Chromec
function fixNumericScrolling() {
$$( "input[type=number]" ).addEvent( "mousewheel", function(e) {
    stopAll(e);     
} );
}

function stopAll(e) {
if( typeof( e.preventDefault               ) != "undefined" ) e.preventDefault();
if( typeof( e.stopImmediatePropagation     ) != "undefined" ) e.stopImmediatePropagation();
if( typeof( event ) != "undefined" ) {
    if( typeof( event.preventDefault           ) != "undefined" ) event.preventDefault();
    if( typeof( event.stopImmediatePropagation ) != "undefined" ) event.stopImmediatePropagation();
}

return false;
}
0
syb

自分でこれを解決しようとしている間に、<input type="number"/>の親要素でキャッチされたイベントを再起動しようとすることで、番号の変更を無効にしながらページのスクロールと入力のフォーカスを実際に保持できることに気付きました単純に次のように、それがキャッチされました:

e.target.parentElement.dispatchEvent(e);

ただし、これによりブラウザコンソールでエラーが発生し、意図的に無効なコードであるため、どこでも機能することは保証されません(Firefoxでのみテストしました)。

少なくともFirefoxとChromiumでうまく機能する別の解決策は、次のように<input>要素readOnlyを一時的に作成することです。

function handleScroll(e) {
  if (e.target.tagName.toLowerCase() === 'input'
    && (e.target.type === 'number')
    && (e.target === document.activeElement)
    && !e.target.readOnly
  ) {
      e.target.readOnly = true;
      setTimeout(function(el){ el.readOnly = false; }, 0, e.target);
  }
}
document.addEventListener('wheel', function(e){ handleScroll(e); });

私が気づいた副作用の1つは、readOnlyフィールドに異なるスタイリングがある場合、フィールドが一瞬ちらつくことがありますが、少なくとも私の場合、これはそうではないようです問題。

同様に、(Jamesの回答で説明されているように)readOnlyプロパティを変更する代わりに、フィールドをblur()してからfocus()戻すことができますが、使用中のスタイルによっては、ちらつきが発生する場合があります。

または、他のコメントで述べたように、代わりにイベントでpreventDefault()を呼び出すことができます。フォーカスがあり、マウスカーソルの下にある数値入力のwheelイベントのみを処理すると仮定すると(上記の3つの条件が意味するもの)、ユーザーエクスペリエンスへの悪影響はほとんどありません。

0
Rimas Kudelis