Отключить прокрутку на `<input type = number>` - PullRequest
94 голосов
/ 15 марта 2012

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

Ответы [ 11 ]

76 голосов
/ 30 декабря 2013

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

НО.Я бы избегал прослушивания события 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')
})

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

23 голосов
/ 19 ноября 2016
$(document).on("wheel", "input[type=number]", function (e) {
    $(this).blur();
});
19 голосов
/ 11 февраля 2013
input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(event){ this.blur() })

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

Пример jQuery и кросс-браузерное решение см. В связанном вопросе:

Прослушиватель событий HTML5 для прокрутки ввода чисел - только Chrome

13 голосов
/ 26 июля 2016

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

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

13 голосов
/ 20 сентября 2013

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

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

input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(evt){ evt.preventDefault(); })
6 голосов
/ 28 июня 2018

Вы можете просто использовать атрибут 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 голосов
/ 25 июня 2015

Сначала вы должны остановить событие mousewheel одним из следующих способов:

  1. Отключение с помощью mousewheel.disableScroll
  2. Перехватывает с e.preventDefault();
  3. Сняв фокус с элемента el.blur();

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

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

$('input[type=number]').on('mousewheel', function(){
  var el = $(this);
  el.blur();
  setTimeout(function(){
    el.focus();
  }, 10);
});
2 голосов
/ 29 ноября 2018

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

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

2 голосов
/ 03 апреля 2018

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

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

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

0 голосов
/ 22 мая 2019

Пытаясь решить эту проблему для себя, я заметил, что на самом деле можно сохранить прокрутку страницы и фокус ввода, отключив изменения чисел, попытавшись повторно запустить перехваченное событие в родительском элементе * 1001.* на котором он был пойман, просто так:

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() его обратно, но again, в зависимости от используемых стилей, может возникнуть некоторое мерцание.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...