javascript - Inaktivera rullning på `<input type=number>`
Är det möjligt att inaktivera rullningshjulet från att ändra numret i ett inmatningsfält för nummer? Jag har lekt med webkit-specifik CSS för att ta bort spinnern men jag skulle vilja bli av med detta beteende helt och hållet. Jag gillar att använda type=number eftersom det visar ett bra tangentbord på iOS.
Svar #1
Förhindra standardbeteendet för musens rulle-händelse på input-number-element som föreslagits av andra (att anropa "blur()" skulle normalt inte vara det föredragna sättet att göra det, eftersom det inte skulle vara vad användaren vill).
MEN. Jag skulle undvika att lyssna på musens rullhjuls-händelse på alla input-number-element hela tiden och bara göra det när elementet är i fokus (det är då problemet uppstår). Annars kan användaren inte scrolla sidan när muspekaren är någonstans över ett input-number-element.
Lösning för jQuery:
// disable mousewheel on a input number field when in focus
// (to prevent Chromium 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')
})
(Delegera fokus-händelser till det omgivande formelementet - för att undvika för många händelselyssnare, vilket är dåligt för prestandan.)
Svar #2
En händelselyssnare för att härska över dem alla
Detta är liknande @Simon Perepelitsas svar i ren JS, men lite enklare, eftersom det sätter en händelselyssnare på dokumentelementet för alla inmatningar och kontrollerar om det fokuserade elementet är av typen nummerinmatning:
document.addEventListener("wheel", function(event){
if(document.activeElement.type === "number"){
document.activeElement.blur();
}
});
Om du vill stänga av värdescrollningsbeteendet på vissa fält efter klass/id, men inte andra lägger du bara till && och motsvarande dokumentväljare istället:
document.addEventListener("wheel", function(event){
if(document.activeElement.type === "number" &&
document.activeElement.classList.contains("noscroll"))
{
document.activeElement.blur();
}
});
med detta:
<input type="number" class="noscroll"/>
Om en input har klassen noscroll kommer det inte att förändras vid scrollning, annars förblir allt annat samma.
Testa här med JSFiddle
Svar #3
$(document).on("wheel", "input[type=number]", function (e) {
$(this).blur();
});
Svar #4
Du kan enkelt använda HTML-attributet onwheel.
Det här alternativet har ingen effekt på scrollning över andra element på sidan.
Och att lägga till en lyssnare för alla inmatningar fungerar inte i inmatningar som skapas dynamiskt senare.
Dessutom kan du ta bort inmatningspilarna med 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()" />Svar #5
Jag har ett alternativt förslag. Problemet jag ser med de flesta vanliga rekommendationerna om att avfyra ett blur-evenemang är att det har oväntade bieffekter. Det är inte alltid bra att ta bort ett fokusläge oväntat.
Varför inte detta istället?
<input type="number" onwheel="return false;" />Det är mycket enkelt och rakt på sak, lätt att genomföra, och inga biverkningar som jag kan komma på.
Svar #6
ReactJS-lösning
För de som behöver en React-lösning, här är en onWheel-hanterare för din type="number"-input för att förhindra att numret ändras och förhindra att sidan rullar medan användaren försöker scrolla över inputfältet. Slutligen kommer den att återfokusera på inputfältet så att användaren kan fortsätta redigera som avsett:
const numberInputOnWheelPreventChange = (e) => {
// Prevent the input value change
e.target.blur()
// Prevent the page/container scrolling
e.stopPropagation()
// Refocus immediately, on the next tick (after the current function is done)
setTimeout(() => {
e.target.focus()
}, 0)
}
return <input type="number" onWheel={numberInputOnWheelPreventChange}/>
Svar #7
input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(event){ this.blur() })
http://jsfiddle.net/bQbDm/2/
För jQuery-exempel och en lösning som fungerar i flera webbläsare, se relaterad fråga:
HTML5-händelselyssnare för nummerinmatningsrullning - endast Chrome
Svar #8
För alla som arbetar med React och letar efter en lösning. Jag har upptäckt att det enklaste sättet är att använda onWheelCapture-prop på Input-komponenten på detta sätt:
onWheelCapture={e => {
e.target.blur()
}}
Svar #9
@Semyon Perepelitsa
Det finns en bättre lösning för detta. Blur tar bort fokus från inputfältet och det är en bieffekt som du inte vill ha. Du bör istället använda evt.preventDefault. Detta förhindrar standardbeteendet för inputfältet när användaren scrollar. Här är koden:
input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(evt){ evt.preventDefault(); })
