Отключить прокрутку на `<input type = number>`

Можно ли отключить колесо прокрутки, изменяющее номер в поле номера ввода? Я перепутал с CSS, специфичным для webkit, чтобы удалить счетчик, но я хотел бы полностью избавиться от этого поведения. Мне нравится использовать type=number, так как он вызывает хорошую клавиатуру на iOS.

Ответ 1

Предотвратите поведение по умолчанию для события mousewheel на элементах входного номера, как это было предложено другими (вызов "blur()" обычно не является предпочтительным способом сделать это, потому что этого не будет, что хочет пользователь).

НО. Я бы избегал прослушивания события mousewheel на всех элементах входного номера все время и делал бы это только тогда, когда элемент находится в фокусе (то есть, когда проблема существует). В противном случае пользователь не сможет прокрутить страницу, когда указатель мыши находится где-либо над элементом числа ввода.

Решение для 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')
})

(делегировать события фокуса окружающему элементу формы - чтобы избежать многих прослушивателей событий, которые ухудшают производительность.)

Ответ 2

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

Ответ 4

@Семен Перепелица

Для этого есть лучшее решение. Blur удаляет фокус со входа, и это побочный эффект, который вы не хотите. Вместо этого вы должны использовать evt.preventDefault. Это предотвращает поведение ввода по умолчанию при прокрутке пользователя. Вот код:

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

Ответ 5

Один прослушиватель событий для управления всеми ними

Это похоже на ответ @Semyon Perepelitsa в чистом js, но немного проще, поскольку он помещает один прослушиватель событий в элемент документа и проверяет, является ли сфокусированный элемент числом:

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, он не изменится при прокрутке, иначе все останется прежним.

Ответ 6

Сначала вы должны остановить событие mousewheel:

  • Отключить его с помощью mousewheel.disableScroll
  • Перехватить его с помощью e.preventDefault();
  • Удалив фокус из элемента el.blur();

Первые два подхода останавливают окно от прокрутки, а последнее удаляет фокус из элемента; оба из которых являются нежелательными результатами.

Обходным путем является использование el.blur() и переориентация элемента после задержки:

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

Ответ 7

Вы можете просто использовать атрибут 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()" />

Ответ 8

Предоставленные ответы не работают в Firefox (Quantum). Слушатель события должен быть изменен с колесика мыши на колесо:

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

Этот код работает на Firefox Quantum и Chrome.

Ответ 9

Для тех, кто работает с React и ищет решение. Я обнаружил, что самый простой способ - использовать пропеллер onWheelCapture в компоненте Input следующим образом:

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

Ответ 10

Пытаясь решить эту проблему для себя, я заметил, что на самом деле можно сохранить прокрутку страницы и фокус ввода, отключив изменения номера, попытавшись повторно запустить перехваченное событие в родительском элементе <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); });

Один побочный эффект, который я заметил, заключается в том, что оно может вызвать мерцание поля в течение доли секунды, если у вас другой стиль для полей readOnly, но, по крайней мере, в моем случае это не похоже на проблема.

Точно так же (как объяснено в ответе Джеймса) вместо изменения свойства readOnly вы можете blur() поле и затем focus() вернуть его обратно, но опять же, в зависимости от используемых стилей, может возникнуть некоторое мерцание.

В качестве альтернативы, как упоминалось в других комментариях здесь, вы можете просто позвонить preventDefault() на событие вместо этого. Предполагая, что вы обрабатываете только события wheel на числовых входах, которые находятся в фокусе и под курсором мыши (что означают три вышеуказанных условия), отрицательное влияние на взаимодействие с пользователем будет практически нулевым.

Ответ 11

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

Ответ 12

Вариант машинописного текста

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

Ответ 13

Ниже исправление css выглядит проще:

input[type=number]::-webkit-inner-spin-button, 
input[type=number]::-webkit-outer-spin-button { 
-webkit-appearance: none; 
margin: 0; 
}

Ссылка