Нажмите кнопку запуска триггеров

168

У меня есть страница с двумя кнопками. Один является <button>элементом, а другой является <input type="submit">. Кнопки появляются на странице в таком порядке. Если я нахожусь в текстовом поле в любом месте формы и нажимаю <Enter>, clickсобытие элемента кнопки срабатывает. Я предполагаю, что это потому, что элемент кнопки сидит первым.

Я не могу найти ничего похожего на надежный способ установки кнопки по умолчанию, и я не хочу этого делать в данный момент. В отсутствие чего-либо лучшего я зафиксировал нажатие в любом месте формы и, если это <Enter>была нажатая клавиша, я просто отрицаю это:

$('form').keypress( function( e ) {
  var code = e.keyCode || e.which;

  if( code === 13 ) {
    e.preventDefault();
    return false; 
  }
})

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

Кто-нибудь знает более сложную технику для этого?

Точно так же, есть ли подводные камни в этом решении, о которых я просто не знаю?

Спасибо.

Роб Уилкерсон
источник
1
Это может произойти при использовании угловых реактивных форм, не только полезных для JQuery, но и для угловой разработки.
HDJEMAI

Ответы:

362

С помощью

<button type="button">Whatever</button>

должен сделать свое дело.

Причина в том, что тип кнопки внутри формы неявно установлен на submit. Как говорит zzzzBoz, Spec говорит, что первым buttonили inputс type="submit"чем то, что срабатывает в этой ситуации. Если вы специально установили type="button", то браузер снимает его с рассмотрения.

Бешеный пес
источник
1
сладкий, спасибо, похоже, кнопки в IE8 для меня захвата <enter> кликов, type="button"кажется, чтобы решить эту проблему ... Спасибо! PS любая идея, почему это? ie8 рассматриваете кнопки как тип отправки? Weird.
Куанг Ван
3
Хороший ответ, это намекает браузеру, какие кнопки не являются кнопками отправки, поэтому он может делать правильные вещи без изменения порядка разметки.
Дон Сполдинг
2
Ответ @ Лейнстера покрывает причину этой причуды - «Кнопка без атрибута типа обрабатывается так же, как кнопка с типом, установленным для отправки».
Ведро
2
То же самое относится к <input type="submit"/>(будет вызывать щелчок) и <input type="button"/>(не будет вызывать щелчок)
Marius Balčytis
1
Невероятно !! Я был так смущен.
Маргус Пала
54

Очень важно прочитать спецификации HTML, чтобы действительно понять, какое поведение следует ожидать:

Спецификация HTML5 прямо заявляет, что происходит вimplicit submissions :

Кнопка по умолчанию для элемента формы - это первая кнопка отправки в древовидном порядке, владельцем формы которой является этот элемент формы.

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

Это не было явно указано в спецификации HTML4, однако браузеры уже реализовали то, что описано в спецификации HTML5 (именно поэтому она включена явно).

Изменить, чтобы добавить:

Самый простой ответ, который я могу придумать, - это поместить кнопку «Отправить» в качестве первого [type="submit"]элемента в форме, добавить отступы внизу формы с помощью css и расположить кнопку «Отправить» внизу, где вам это нужно.

zzzzBov
источник
Там я проклинал IE, оказалось, что это была моя небрежная разметка с самого начала! Ура!
Шоусон
2
Вау ... Спасибо, сэр. Это была случайная находка. Я даже не мог понять, почему событие нажатия кнопки запускается при нажатии клавиши ввода, но ваша цитата привела меня к w3.org/TR/html5/forms.html#implicit-submission
chemoish
Ссылка не работает. Я думаю, что w3c.github.io/html/sec-forms.html#implicit-submission - это новый URL.
TJ.
22

Я не думаю, что вам нужен JavaScript или CSS, чтобы это исправить.

В соответствии со спецификацией html 5 для кнопок кнопка без атрибута типа обрабатывается так же, как кнопка с типом, установленным в «submit», т.е. как кнопка для отправки содержащей ее формы. Установка типа кнопки «кнопка» должна предотвратить поведение, которое вы видите.

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

Лейнстер
источник
13

Нажав «Enter» на выделенном, <input type="text">вы инициируете событие «click» на первом позиционированном элементе: <button>или <input type="submit">. Если вы нажмете «Enter» в<textarea> , вы просто создадите новую текстовую строку.

Смотрите пример здесь .

Ваш код мешает сделать новую текстовую строку в <textarea> , поэтому вы должны ловить нажатие клавиши только для<input type="text"> .

Но зачем вам нажимать Enterв текстовом поле? Если вы хотите отправить форму, нажав «Enter», но она <button>должна оставаться первой в макете, просто поиграйте с разметкой: поместите<input type="submit"> код перед<button> и используйте CSS, чтобы сохранить нужный макет.

Перехват «Enter» и сохранение разметки:

$('input[type="text"]').keypress(function (e) {
    var code = e.keyCode || e.which;
    if (code === 13)
    e.preventDefault();
    $("form").submit(); /*add this, if you want to submit form by pressing `Enter`*/
});
Feniks502
источник
Разве оператор if не должен иметь скобки для выполнения обоих операторов только при нажатии клавиши Enter? В противном случае отправка будет происходить при каждом нажатии клавиши. Напоминает мне о провал. :)
Данмизер
13

Когда бы вы ни использовали <button>элемент по умолчанию, он считает эту кнопку, type="submit"поэтому, если вы определите кнопку, type="button"он не будет рассматривать ее <button>как кнопку отправки.

Рам Тота
источник
2

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

Sparafusile
источник
4
Я не думаю, что проблема в том, что форма отправляется, а в том, что она запускает clickдействие над элементами кнопки, желание - непреднамеренное последствие
Мартин Йесперсен
Ты прав. В любом случае, результат один и тот же - вам нужно захватить клавишу ввода, чтобы предотвратить отправку нежелательных форм.
Sparafusile
2

Вы можете использовать JavaScript, чтобы заблокировать отправку формы до соответствующего времени. Очень грубый пример:

<form onsubmit='return false;' id='frmNoEnterSubmit' action="index.html">

    <input type='text' name='txtTest' />

    <input type='button' value='Submit' 
        onclick='document.forms["frmNoEnterSubmit"].onsubmit=""; document.forms["frmNoEnterSubmit"].submit();' />

</form>

Нажатие клавиши ввода по-прежнему активирует форму для отправки, но JavaScript не позволит отправить ее до тех пор, пока вы фактически не нажмете кнопку.

Дейв
источник
2

Дом пример

  <button onclick="anotherFoo()"> Add new row</button>
  <input type="text" name="xxx" onclick="foo(event)">

Javascript

function foo(event){
   if(event.which == 13 || event.keyCode == 13) // for crossbrowser
   {
     event.preventDefault(); // this code prevents other buttons triggers use this
     // do stuff
   }
}

function anotherFoo(){
  // stuffs.
}

Если вы не используете protectDefault (), сработают другие кнопки.

Мехмет Али Куш
источник
0

Я бы сделал это следующим образом: В обработчике события onclick кнопки (не отправить) проверьте код ключа объекта события. Если это «ввод», я бы вернул false.

Satyajit
источник
Этот код ключа всегда передается, как если бы это был щелчок. В этом и заключается проблема. :-)
Роб Уилкерсон
Тогда, я полагаю, вы делаете это нелегко - обработайте событие onkeydown на кнопке. Обработчику будет передано keyEvent; проверьте код ключа -> если 13, предотвращение дефолта. Таким образом, вы можете фактически позволить пользователям нажимать ввод на этой кнопке без побочного эффекта от выполнения события click.
Сатьяджит
0

Моя ситуация имеет две Submitкнопки внутри элемента формы: Updateи Delete. DeleteКнопка удаляет изображение и изображениеUpdate кнопка обновляет базу данных с текстовыми полями в форме.

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

Я нашел свой ответ на установку кнопки по умолчанию здесь :

<form action="/action_page.php" method="get" id="form1">
  First name: <input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
</form>
<button type="submit" form="form1" value="Submit">Submit</button>

Не используя скрипт, я определил форму, к которой принадлежит каждая кнопка, используя <button> form="bla"атрибут. Я установил для Deleteкнопки форму, которой не существует, и установил Updateкнопку, которую я хотел вызвать, на Enterключе формы, в которой пользователь будет находиться при вводе текста.

Это единственное, что сработало для меня до сих пор.

Дэн Вачон
источник
1
Пожалуйста, проверьте, как ответить на stackoverflow
Морс
0

Вы можете сделать что-то вроде этого.

привязать ваше событие к общей функции и вызвать событие либо нажатием клавиши, либо нажатием кнопки.

например.

function callME(event){
    alert('Hi');
}



$('button').on("click",callME); 
$('input ').keypress(function(event){
  if (event.which == 13) {
    callME(event);
  }
});
newbdeveloper
источник
-1

Я добавил кнопку типа «отправить» в качестве первого элемента формы и сделал ее невидимой ( width:0;height:0;padding:0;margin:0;border-style:none;font-size:0;). Работает как обновление сайта, т.е. я ничего не делаю при нажатии кнопки, кроме того, что сайт загружается снова. У меня работает нормально ...

torabe
источник