Как предотвратить ввод начального пробела в текстовое поле?

Я использую jQuery 2. Как предотвратить ввод пробела в текстовое поле, если это начальный пробел (например, в начале строки)? Я думал, что это сделает это

   $(document).on("keyup","#s" ,function(evt){
     var firstChar = $("#s").val()
     if(evt.keyCode == 32 && firstChar){
       $("#s").val( $("#s").val().trim() )
       console.log(" called ")
       return false;
     }
  })

И в основном это так, но это немного неаккуратно. Вы можете видеть, как пробел вводится, а затем удаляется, и я искал что-то более гладкое, в результате чего пробел вообще не попадает в учебник.


person Dave    schedule 09.02.2018    source источник
comment
Обнаружить нажатие клавиши и предотвратить действие по умолчанию, если был введен пробел..?   -  person Teemu    schedule 10.02.2018
comment
Я не хочу полностью блокировать пробелы, только ведущие пробелы. Я заменил приведенную выше фразу keyup на keydown, но неудивительно, что это не работает.   -  person Dave    schedule 10.02.2018


Ответы (3)


Вы должны понимать разницу между событиями keyup, keypress и keydown:

  • keydown : это первое событие, запускаемое при первом нажатии клавиши
  • нажатие клавиши: это когда происходит ввод
  • keyup : Когда вы «отпускаете» клавишу

Итак, у вас есть "нажатие клавиши -> нажатие клавиши -> заполнить ввод -> отпустить клавишу"

В вашем сценарии вы хотите, чтобы что-то произошло ДО того, как фактический ввод будет заполнен, поэтому вам нужно использовать событие keydown вместо keyup

Оттуда возврат false приведет к остановке распространения события, поэтому "нажатие клавиши -> // Здесь все сломается // -> нажатие клавиши -> заполнить ввод -> отпустить клавишу"

Последнее — это ваше состояние. В своем коде вы не проверяете, действительно ли firstChar пуст, вы просто каждый раз что-то получаете, потому что получаете значение. Просто немного изменив ваше условие, код заработал.

Вот рабочая демонстрация:

$(document).on("keydown","#hello" ,function(evt){
     var firstChar = $("#hello").val()
     if(evt.keyCode == 32 && firstChar == ""){
     	return false;
     }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="hello">

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

ИЗМЕНИТЬ:

После комментария ОП о том, что вы можете ввести пробел, набрав пробел, а затем вернувшись перед первой буквой, ниже приведено исправление, которое помогает.

По сути, теперь я основываю свой код не на «первом символе», а на позиции курсора.

Если курсор находится в позиции 0, мы не позволяем пользователю вводить пробел, в противном случае все в порядке.

Новый код JS выглядит так:

$(document).on("keydown","#hello" ,function(evt){
     var caretPos = $(this)[0].selectionStart
     if(evt.keyCode == 32 && caretPos == 0){
        return false;
     }
});

ИЗМЕНИТЬ 2:

Рик Хичкок комментарий:

$() возвращает коллекцию jQuery. Вы можете получить доступ к отдельному элементу коллекции, обратившись к его индексу ([0], [1], [2], ...). У вас уже есть отдельный элемент (это), и нет необходимости помещать его в коллекцию jQuery, чтобы вы могли сразу же взять его обратно.

Принимая это во внимание, $(this)[0].selectionStart можно заменить на this.selectionStart

person Rafik Tighilt    schedule 09.02.2018
comment
Если кто-то уже ввел букву «а» в текстовое поле, а затем пытается ввести пробел перед буквой «а», то в вашей демонстрации он успешен. Я бы хотел, чтобы они не входили в это начальное пространство, даже если в текстовом поле есть данные. - person Dave; 10.02.2018
comment
Я отредактировал свой ответ с учетом этого случая с объяснением. - person Rafik Tighilt; 10.02.2018
comment
Я бы не назвал ваше редактирование взломом, я бы назвал его правильным решением. Вы можете немного упростить, используя this.selectionStart. - person Rick Hitchcock; 10.02.2018
comment
(Обратите внимание, что $(this)[0] эквивалентно this.) - person Rick Hitchcock; 10.02.2018
comment
Это то, что я заметил, когда пробовал, но можете ли вы дать ссылку или объяснение, чтобы я мог пойти дальше? Изменить: я нашел ТАК вопрос, который задал его, спасибо :) - person Rafik Tighilt; 10.02.2018
comment
$() возвращает коллекцию jQuery. Вы можете получить доступ к отдельному элементу коллекции, обратившись к его индексу ([0], [1], [2], ...). У вас уже есть отдельный элемент (this), и нет необходимости помещать его в коллекцию jQuery только для того, чтобы вы могли немедленно извлечь его обратно. - person Rick Hitchcock; 10.02.2018
comment
Я добавил ваше объяснение к ответу, чтобы люди могли понять, даже если они не читают комментарии. Спасибо ! - person Rafik Tighilt; 10.02.2018

Вот один пример предотвращения пробелов в начале и в конце.

 $(document).on("keypress","#s" ,function(evt){
     var firstChar = $("#s").val()
     if(evt.keyCode == 32){
        var cursorPos = $("#s").prop("selectionStart");
        //Prevents spaces in Beginning and more than on at the end
        if(cursorPos == 0 || (cursorPos == firstChar.length && firstChar[firstChar.length-1] == " "))
        {
            evt.preventDefault();
        }
     }
  })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="s">  

person sweting    schedule 09.02.2018

вот решение.

просто используйте keydown вместо keyup и в условии firstChar=="" и используйте evt.preventDefault(evt); учитывая приведенный ниже код.

$(document).on("keydown","#s" ,function(evt){    
 var firstChar = $("#s").val();
 if(evt.keyCode == 32 && firstChar==""){
   evt.preventDefault(evt);
   $("#s").val( $("#s").val().trim() )
   console.log(" called ")
   return false;
 }

})

person Mowazzem Hosen    schedule 09.02.2018
comment
Эй, это та же проблема, что и в ответе Рафика: если в текстовом поле уже есть текст, кто-то может ввести начальный пробел перед первым символом. - person Dave; 10.02.2018