web-dev-qa-db-de.com

Deaktivieren Sie das Scrollen bei <Eingangstyp = Nummer>

Ist es möglich, das Scrollrad zu deaktivieren, wenn die Zahl in einem Eingabefeld geändert wird? Ich habe mich mit webkit-spezifischem CSS beschäftigt, um den Spinner zu entfernen. Ich mag type=number, da auf iOS eine Nice-Tastatur angezeigt wird. 

89
kjs3

Verhindern Sie das Standardverhalten des Mausrad-Ereignisses bei Eingabenummernelementen, wie von anderen vorgeschlagen (der Aufruf von "blur ()" wäre normalerweise nicht die bevorzugte Methode, da dies nicht das ist, was der Benutzer möchte).

ABER. Ich würde es vermeiden, ständig auf das Mausradereignis für alle Eingabe-Nummer-Elemente zu achten und es nur dann zu tun, wenn das Element im Fokus ist (dann existiert das Problem). Andernfalls der Benutzer kann die Seite nicht scrollen wenn sich der Mauszeiger irgendwo über einem Element mit Eingabe befindet. 

Lösung für 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')
})

(Delegieren Sie Fokusereignisse an das umgebende Formularelement - um zu vermeiden, dass viele Ereignisempfänger die Leistung beeinträchtigen.)

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

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

Für jQuery-Beispiel und eine browserübergreifende Lösung siehe verwandte Frage:

HTML5-Ereignis-Listener für Zahleneingabe - nur Chrome

17

Ein Ereignis-Listener, um alle zu regieren

Dies ist der Antwort von @Semyon Perepelitsa in pure js ähnlich, jedoch etwas einfacher, da ein Ereignis-Listener auf das Dokumentelement gesetzt wird und geprüft wird, ob das fokussierte Element eine Zahleneingabe ist:

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

Wenn Sie das Verhalten zum Verschieben von Werten in einigen Feldern deaktivieren möchten, nicht aber in anderen, tun Sie dies einfach:

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

mit diesem:

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

Wenn eine Eingabe die Noscroll-Klasse hat, wird sie beim Scrollen nicht geändert, ansonsten bleibt alles gleich.

12
Peter Rakmanyi

@ Semyon Perepelitsa

Dafür gibt es eine bessere Lösung. Blur entfernt den Fokus von der Eingabe und das ist ein Nebeneffekt, den Sie nicht wünschen. Verwenden Sie stattdessen evt.preventDefault. Dies verhindert das Standardverhalten der Eingabe, wenn der Benutzer einen Bildlauf durchführt. Hier ist der Code:

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

Sie können einfach das HTML onwheel Attribut verwenden.

Diese Option hat keine Auswirkungen auf das Scrollen über andere Elemente der Seite.

Und fügen Sie einen Listener für alle Eingaben hinzu, die nicht in Eingaben funktionieren, die dynamisch nachträglich erstellt wurden.

Zusätzlich können Sie die Eingabepfeile mit CSS entfernen.

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

Zuerst müssen Sie das Mausrad-Ereignis stoppen, indem Sie entweder

  1. Deaktivieren mit mousewheel.disableScroll
  2. Abfangen mit e.preventDefault();
  3. Durch Entfernen des Fokus vom Element el.blur();

Die ersten beiden Ansätze verhindern, dass das Fenster scrollt, und der letzte entfernt den Fokus vom Element. Beides sind unerwünschte Ergebnisse.

Eine Problemumgehung besteht darin, el.blur() zu verwenden und das Element nach einer Verzögerung neu zu fokussieren:

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

Die bereitgestellten Antworten funktionieren nicht in Firefox (Quantum). Der Ereignislistener muss vom Mausrad zum Rad geändert werden:

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

Dieser Code funktioniert mit Firefox Quantum und Chrome.

2
Mathias Bank

Für alle, die mit React arbeiten und nach einer Lösung suchen. Ich habe herausgefunden, dass der einfachste Weg ist, onWheelCapture prop in der Input-Komponente wie folgt zu verwenden:

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

Bei dem Versuch, dies für mich selbst zu lösen, ist mir aufgefallen, dass es tatsächlich möglich ist, das Scrollen der Seite und den Fokus der Eingabe beizubehalten, während Änderungen der Nummer deaktiviert werden, indem versucht wird, das erfasste Ereignis für das übergeordnete Element von <input type="number"/> erneut auszulösen. auf dem es gefangen wurde, einfach so:

e.target.parentElement.dispatchEvent(e);

Dies verursacht jedoch einen Fehler in der Browserkonsole und funktioniert möglicherweise nicht überall (ich habe es nur in Firefox getestet), da es sich um absichtlich ungültigen Code handelt.

Eine andere Lösung, die zumindest in Firefox und Chromium gut funktioniert, besteht darin, das <input> -Element readOnly vorübergehend so zu gestalten:

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); });

Ein Nebeneffekt, den ich bemerkt habe, ist, dass das Feld für den Bruchteil einer Sekunde flackern kann, wenn Sie für readOnly Felder ein anderes Design haben, aber zumindest für meinen Fall scheint dies kein zu sein Problem.

In ähnlicher Weise können Sie (wie in James 'Antwort erläutert) anstelle der Eigenschaft readOnly das Feld blur() und anschließend focus() zurücksetzen, je nach verwendeten Stilen jedoch auch einige es kann zu flackern kommen.

Alternativ können Sie, wie in anderen Kommentaren erwähnt, stattdessen einfach preventDefault() für das Ereignis aufrufen. Unter der Annahme, dass Sie nur wheel -Ereignisse für Zahleneingaben verarbeiten, die im Fokus und unter dem Mauszeiger stehen (dies sind die drei oben genannten Bedingungen), wäre eine negative Auswirkung auf die Benutzererfahrung so gut wie keine.

0
Rimas Kudelis