Kliknij przycisk Enter wyzwalacze

168

Mam stronę z dwoma przyciskami. Jeden to <button>element, a drugi to <input type="submit">. Przyciski pojawiają się na stronie w tej kolejności. Jeśli znajdę się w polu tekstowym w dowolnym miejscu formularza i naciśnę <Enter>, clickzostanie wyzwolone zdarzenie elementu przycisku . Zakładam, że to dlatego, że element przycisku znajduje się jako pierwszy.

Nie mogę znaleźć niczego, co wygląda na niezawodny sposób ustawienia domyślnego przycisku, ani też nie chcę tego robić w tym momencie. Wobec braku czegoś lepszego złapałem naciśnięcie klawisza w dowolnym miejscu formularza i, jeśli to był <Enter>klawisz, który został naciśnięty, po prostu go neguję:

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

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

O ile wiem, wydaje się, że działa, ale wydaje się niesamowicie uparty.

Czy ktoś zna bardziej wyrafinowaną technikę robienia tego?

Podobnie, czy są jakieś pułapki w tym rozwiązaniu, których po prostu nie jestem świadomy?

Dzięki.

Rob Wilkerson
źródło
1
Może się to zdarzyć również w przypadku używania kątowych form reaktywnych, przydatnych nie tylko dla JQuery, ale także dla rozwoju kątowego.
HDJEMAI

Odpowiedzi:

362

Za pomocą

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

powinien załatwić sprawę.

Przyczyną jest to, że przycisk wewnątrz formularza ma niejawnie ustawiony typ submit. Jak mówi zzzzBoz, specyfikacja mówi, że w tej sytuacji wyzwalany jest pierwszy buttonlub inputz type="submit". Jeśli ustawisz to specjalnie type="button", przeglądarka nie bierze tego pod uwagę.

Wściekły pies
źródło
1
słodko, dzięki, wygląda na to, że przyciski w IE8 przechwytują kliknięcia <enter>, type="button"wydaje się , że rozwiązują ten problem ... Dzięki! ps jakiś pomysł, dlaczego tak jest? ie8 traktuje przyciski jako typ przesyłania? Dziwne.
Quang Van
3
Dobra odpowiedź, to podpowiada przeglądarce, które przyciski nie są przyciskami wysyłania, więc może zrobić to dobrze bez zmiany kolejności znaczników.
Don Spaulding
2
Odpowiedź @ Leinster obejmuje powód tego dziwactwa - „Przycisk bez atrybutu typu jest traktowany tak samo jak przycisk z typem ustawionym do przesłania”.
Bucket
2
To samo dotyczy <input type="submit"/>(spowoduje kliknięcie) i <input type="button"/>(nie uruchomi kliknięcia)
Marius Balčytis
1
Nie do wiary!! Byłem taki zdezorientowany.
Margus Pala
54

Ważne jest, aby przeczytać specyfikację HTML, aby naprawdę zrozumieć, jakiego zachowania można się spodziewać:

Specyfikacja HTML5 wyraźnie określa, co dzieje się wimplicit submissions :

Domyślnym przyciskiem elementu formularza jest pierwszy przycisk przesyłania w porządku drzewa, którego właścicielem jest ten element formularza.

Jeśli program użytkownika umożliwia niejawne przesyłanie formularza przez użytkownika (na przykład na niektórych platformach naciśnięcie klawisza „enter”, gdy pole tekstowe jest skoncentrowane, niejawnie przesyła formularz), robi to dla formularza, którego domyślny przycisk ma zdefiniowaną aktywację zachowanie musi powodować, że agent użytkownika uruchamia kroki aktywacji kliknięciem syntetycznym na tym domyślnym przycisku.

Nie było to wyraźnie określone w specyfikacji HTML4, jednak przeglądarki już implementowały to, co jest opisane w specyfikacji HTML5 (dlatego jest to wyraźnie uwzględnione).

Edytuj, aby dodać:

Najprostszą odpowiedzią, jaką przychodzi mi do głowy, jest umieszczenie przycisku przesyłania jako pierwszego [type="submit"]elementu formularza, dodanie dopełnienia u dołu formularza za pomocą css i absolutnie umieszczenie przycisku przesyłania u dołu, tam, gdzie chcesz.

zzzzBov
źródło
Przeklinałem IE, okazuje się, że przez cały czas był to mój niechlujny znacznik! Twoje zdrowie!
Shawson,
2
Wow ... Dziękuję dobry panie. To było przypadkowe znalezisko. Nie mogłem nawet pojąć, dlaczego zdarzenie kliknięcia było uruchamiane po naciśnięciu klawisza Enter, ale Twój cytat doprowadził mnie do w3.org/TR/html5/forms.html#implicit-submission
chemoish
Link jest uszkodzony. Myślę, że w3c.github.io/html/sec-forms.html#implicit-submission to nowy adres URL.
TJ.
22

Myślę, że nie potrzebujesz javascript lub CSS, aby to naprawić.

Zgodnie ze specyfikacją html 5 dla przycisków przycisk bez atrybutu typu jest traktowany tak samo jak przycisk z typem ustawionym na „wyślij”, czyli jako przycisk do przesłania formularza zawierającego. Ustawienie typu przycisku na „przycisk” powinno zapobiec występującemu zachowaniu.

Nie jestem pewien, czy przeglądarka obsługuje to, ale to samo zachowanie zostało określone w specyfikacji HTML 4.01 dla przycisków, więc spodziewam się, że jest całkiem niezłe.

Leinster
źródło
13

Naciskając „Enter” na fokusie <input type="text">wywołujesz zdarzenie „click” na pierwszym pozycjonowanym elemencie: <button>lub <input type="submit">. Jeśli naciśniesz „Enter” <textarea>, po prostu utworzysz nową linię tekstu.

Zobacz przykład tutaj .

Twój kod uniemożliwia utworzenie nowej linii tekstu <textarea>, więc musisz złapać naciśnięcie klawisza tylko dla <input type="text">.

Ale dlaczego musisz naciskać Enterw polu tekstowym? Jeśli chcesz wysłać formularz, naciskając „Enter”, ale <button>musi pozostać jako pierwszy w układzie, po prostu baw się znacznikami: umieść <input type="submit">kod przed <button>i użyj CSS, aby zapisać potrzebny układ.

Łapanie „Enter” i zapisywanie znaczników:

$('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
źródło
Czy instrukcja if nie powinna mieć nawiasu klamrowego, aby wykonać obie instrukcje tylko po naciśnięciu klawisza Enter? W przeciwnym razie przesyłanie nastąpi po każdym naciśnięciu klawisza. Przypomina mi o niepowodzeniu goto. :)
danmiser
13

Gdziekolwiek używasz <button>elementu domyślnie, on bierze pod uwagę ten przycisk, type="submit"więc jeśli zdefiniujesz przycisk, type="button"nie będzie go traktował <button>jako przycisku przesyłania.

Ram Thota
źródło
2

Naciśnięcie klawisza Enter w polu tekstowym formularza spowoduje domyślnie przesłanie formularza. Jeśli nie chcesz, aby działało w ten sposób, musisz uchwycić klawisz Enter i konsumować go tak, jak zrobiłeś. Nie da się tego obejść. Będzie to działać w ten sposób, nawet jeśli w formularzu nie ma przycisku.

Sparafusile
źródło
4
Nie sądzę, że problem jest, że przedkłada formie, jest to, że wyzwala clickdziałanie na elementy przycisku życzeniem jest niezamierzone konsekwencje
Martin Jespersen
Masz rację. Tak czy inaczej, wynik jest taki sam - musisz uchwycić klawisz Enter, aby zapobiec niechcianym przesyłaniu formularzy.
Sparafusile
2

Możesz użyć javascript, aby zablokować przesyłanie formularzy do odpowiedniego czasu. Bardzo surowy przykład:

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

Naciśnięcie klawisza Enter nadal będzie powodować przesłanie formularza, ale skrypt javascript uniemożliwi jego rzeczywiste przesłanie, dopóki nie naciśniesz przycisku.

Dave
źródło
2

Przykład Dom

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

jeśli nie użyjesz opcji PreventDefault (), zostaną uruchomione inne przyciski.

Mehmet Ali Kuş
źródło
0

Zrobiłbym to w następujący sposób: W programie obsługi zdarzenia onclick przycisku (nie przesyłaj) sprawdź kod klucza obiektu zdarzenia. Jeśli to „enter”, zwróciłbym fałsz.

Satyajit
źródło
Ten kod jest zawsze przekazywany tak, jakby był to kliknięcie. Na tym polega problem. :-)
Rob Wilkerson
Więc myślę, że robisz to na własnej skórze - radzisz sobie również z wydarzeniem onkeydown na buttonie. Do procedury obsługi zostanie przekazany keyEvent; sprawdź keyCode -> jeśli 13, PreventDefault. W ten sposób możesz pozwolić użytkownikom nacisnąć klawisz Enter również na tym przycisku bez efektu ubocznego wykonania zdarzenia kliknięcia.
Satyajit,
0

Moja sytuacja ma dwa Submitprzyciski w elemencie formularza: Updatei Delete. DeletePrzycisk usuwa obraz i Updateprzycisk aktualizuje bazę danych z pól tekstowych w formularzu.

Ponieważ Deleteprzycisk był pierwszy w formularzu, był to domyślny przycisk na Enterklawiszu. Nie to, czego chciałem. Użytkownik spodziewałby się trafienia Enterpo zmianie niektórych pól tekstowych.

Znalazłem swoją odpowiedź na ustawienie przycisku domyślnego tutaj :

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

Nie używając żadnego skryptu, zdefiniowałem formularz, do którego należy każdy przycisk, używając <button> form="bla"atrybutu. Ustawiłem Deleteprzycisk na formularz, który nie istnieje, i ustawiłem Updateprzycisk, który chciałem wywołać na Enterklawiszu, na formularz, w którym użytkownik będzie się znajdował podczas wprowadzania tekstu.

To jedyna rzecz, która do tej pory działała dla mnie.

Dan Vachon
źródło
0

Możesz zrobić coś takiego.

przypisz swoje zdarzenie do wspólnej funkcji i wywołaj zdarzenie naciskając klawisz lub przycisk.

na przykład.

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



$('button').on("click",callME); 
$('input ').keypress(function(event){
  if (event.which == 13) {
    callME(event);
  }
});
newbdeveloper
źródło
-1

Dodałem przycisk typu „wyślij” jako pierwszy element formularza i uczyniłem go niewidocznym ( width:0;height:0;padding:0;margin:0;border-style:none;font-size:0;). Działa jak odświeżanie strony, tzn. Nie robię nic po naciśnięciu przycisku poza tym, że strona jest ponownie ładowana. U mnie działa dobrze ...

torabe
źródło