入力数値フィールドの数値を変更するスクロールホイールを無効にすることはできますか?私はスピナーを削除するためにwebkit固有のCSSをいじりましたが、この動作を完全に取り除きたいと思います。type=number
iOSで素晴らしいキーボードが表示されるので、使用するのが好きです。
onscroll
ハンドラーを追加するとどうevent.preventDefault()
なりますか?
入力数値フィールドの数値を変更するスクロールホイールを無効にすることはできますか?私はスピナーを削除するためにwebkit固有のCSSをいじりましたが、この動作を完全に取り除きたいと思います。type=number
iOSで素晴らしいキーボードが表示されるので、使用するのが好きです。
onscroll
ハンドラーを追加するとどうevent.preventDefault()
なりますか?
回答:
他の人が提案したようなinput-number要素でのマウスホイールイベントのデフォルトの動作を防止します(「blur()」を呼び出すのは、ユーザーが望むものではないため、通常は推奨される方法ではありません)。
だが。すべてのinput-number要素でマウスホイールイベントを常にリッスンすることは避け、要素がフォーカスされているとき(つまり、問題が存在するとき)だけそれを実行します。それ以外の場合、マウスポインターが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('wheel.disableScroll', function (e) {
e.preventDefault()
})
})
$('form').on('blur', 'input[type=number]', function (e) {
$(this).off('wheel.disableScroll')
})
(フォーカスイベントを周囲のフォーム要素に委譲します-パフォーマンスに悪影響を与える多くのイベントリスナーを回避します。)
$(document).on("wheel", "input[type=number]", function (e) {
$(this).blur();
});
これは純粋なjsでの@Simon Perepelitsaの回答に似ていますが、ドキュメント要素に1つのイベントリスナーを配置し、フォーカスされた要素が数値入力であるかどうかをチェックするため、少し単純です。
document.addEventListener("wheel", function(event){
if(document.activeElement.type === "number"){
document.activeElement.blur();
}
});
一部のフィールドで値のスクロール動作をオフにしたいが、他のフィールドではオフにしたくない場合は、代わりにこれを行います。
document.addEventListener("wheel", function(event){
if(document.activeElement.type === "number" &&
document.activeElement.classList.contains("noscroll"))
{
document.activeElement.blur();
}
});
これとともに:
<input type="number" class="noscroll"/>
入力にnoscrollクラスがある場合、スクロール時に変更されません。それ以外の場合、すべてが同じままです。
wheel
代わりにイベントを使用してくださいmousewheel
。参照:developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event PS。反対票を投じたのは私ではありません。
input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(event){ this.blur() })
jQueryの例とクロスブラウザソリューションについては、関連する質問を参照してください。
$(':input[type=number]' ).live('mousewheel',function(e){ $(this).blur(); });
を使用してすべての数値入力に対してこの方法でなんとかできました。デフォルトを防止する代わりにぼかしを使用したので、ページのスクロールがブロックされません!
live()
は非推奨です。今、あなたは使うべきですon()
: $(':input[type=number]').on('mousewheel',function(e){ $(this).blur(); });
wheel
代わりにイベントを使用してくださいmousewheel
。参考:developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event
単に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()" />
onBlur()
は期待どおりではありませんでした。return false
代わりに、本当に「ホイールで何もしない」ようにシンプルな設定をしました。 <input type="number" onwheel="return false;">
@Semyon Perepelitsa
これにはより良い解決策があります。ぼかしは入力からフォーカスを削除しますが、これは望ましくない副作用です。代わりにevt.preventDefaultを使用してください。これにより、ユーザーがスクロールしたときの入力のデフォルトの動作が妨げられます。これがコードです:
input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(evt){ evt.preventDefault(); })
wheel
代わりにイベントを使用してくださいmousewheel
。参考:developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event
まず、次のいずれかの方法でマウスホイールイベントを停止する必要があります。
mousewheel.disableScroll
e.preventDefault();
el.blur();
最初の2つの方法はどちらもウィンドウのスクロールを停止し、最後の方法は要素からフォーカスを削除します。どちらも望ましくない結果です。
回避策の1つはel.blur()
、遅延の後で要素を使用して再フォーカスすることです。
$('input[type=number]').on('mousewheel', function(){
var el = $(this);
el.blur();
setTimeout(function(){
el.focus();
}, 10);
});
var hadFocus = el.is(':focus');
ぼかしの前に、そしてhadFocsがtrueの場合にのみタイムアウトを設定するガード。
Reactで作業し、解決策を探している人のために。最も簡単な方法は、次のように入力コンポーネントでonWheelCaptureプロップを使用することです。
onWheelCapture={e => {
e.target.blur()
}}
Typescriptは、タイプセーフのためにHTMLElementを使用していることを認識する必要があります。そうでないと、多くのProperty 'type' does not exist on type 'Element'
タイプのエラーが表示されます。
document.addEventListener("mousewheel", function(event){
let numberInput = (<HTMLInputElement>document.activeElement);
if (numberInput.type === "number") {
numberInput.blur();
}
});
自分のためにこれを解決しようとしている間、私はそれがの親要素の上に再火災に巻き込まイベントを試みることによって、番号の変更を無効にしながら、入力のページのスクロールやフォーカスを維持するために実際に可能だということに気づいた<input type="number"/>
、それがキャッチされました、単にこのように:
e.target.parentElement.dispatchEvent(e);
ただし、これはブラウザーコンソールでエラーを引き起こし、意図的に無効なコードであるため、おそらくすべての場所で動作することが保証されていません(私はFirefoxでのみテストしました)。
少なくともFirefoxとChromiumでうまく機能する別の解決策は、次のように一時的に<input>
elementを作成すること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つの条件が意味することです)、ユーザーエクスペリエンスへの悪影響はほとんどありません。
JavaScriptを必要としないソリューションが必要な場合は、一部のHTML機能をCSS疑似要素と組み合わせるとうまくいきます。
span {
position: relative;
display: inline-block; /* Fit around contents */
}
span::after {
content: "";
position: absolute;
top: 0; right: 0; bottom: 0; left: 0; /* Stretch over containing block */
cursor: text; /* restore I-beam cursor */
}
/* Restore context menu while editing */
input:focus {
position: relative;
z-index: 1;
}
<label>How many javascripts can u fit in u mouth?
<span><input type="number" min="0" max="99" value="1"></span>
</label>
これは、コンテンツをクリックすると機能します。 <label>
は、フォームフィールドに関連付けられているのするとフィールドがフォーカスされるため機能します。ただし、フィールド上の疑似要素の「ウィンドウペイン」は、マウスホイールイベントがそれに到達するのをブロックします。
欠点は、上下のスピナーボタンが機能しなくなることですが、とにかくそれらを削除したと言っていました。
理論的には、最初に入力にフォーカスする必要なしにコンテキストメニューを復元できます。ユーザーがスクロールしても:hover
スタイルは発生しません。ブラウザーはパフォーマンス上の理由でスクロール中に再計算を回避するためですが、ブラウザー/デバイスを完全にクロスしていませんそれをテストしました。
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;
}
最も簡単な解決策はonWheel={ event => event.currentTarget.blur() }}
、入力自体を追加することです。