Jeśli formularz zostanie przesłany, ale nie przez żaden konkretny przycisk, taki jak
- naciskając Enter
- za pomocą
HTMLFormElement.submit()
w JS
w jaki sposób przeglądarka ma określić, który z wielu przycisków przesyłania, jeśli w ogóle, ma być użyty jako naciśnięty?
Jest to istotne na dwóch poziomach:
- wywołanie
onclick
procedury obsługi zdarzenia dołączonej do przycisku wysyłania - dane wysłane z powrotem do serwera WWW
Moje dotychczasowe eksperymenty wykazały, że:
- po naciśnięciu EnterFirefox, Opera i Safari używają pierwszego przycisku przesyłania w formularzu
- po naciśnięciu EnterIE używa albo pierwszego przycisku przesyłania, albo żadnego, w zależności od warunków, których nie byłem w stanie zrozumieć
- wszystkie te przeglądarki w ogóle nie używają żadnego do przesłania JS
Co mówi standard?
Jeśli to pomoże, oto mój kod testowy (PHP dotyczy tylko mojej metody testowania, a nie samego pytania)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
</head>
<body>
<h1>Get</h1>
<dl>
<?php foreach ($_GET as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>
<h1>Post</h1>
<dl>
<?php foreach ($_POST as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>
<form name="theForm" method="<?php echo isset($_GET['method']) ? $_GET['method'] : 'get'; ?>" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
<input type="text" name="method" />
<input type="submit" name="action" value="Button 1" onclick="alert('Button 1'); return true" />
<input type="text" name="stuff" />
<input type="submit" name="action" value="Button 2" onclick="alert('Button 2'); return true" />
<input type="button" value="submit" onclick="document.theForm.submit();" />
</form>
</body></html>
źródło
HTML 4 nie wyraża tego wprost. Bieżąca robocza wersja robocza HTML5 określa, że pierwszy przycisk przesyłania musi być domyślny :
źródło
Andrezj prawie go przybił ... ale oto proste rozwiązanie dla różnych przeglądarek.
Weź taką formę:
i zwróć uwagę na to:
Ponieważ specyfikacja W3C wskazuje, że wiele przycisków przesyłania jest poprawnych, ale pomija wskazówki dotyczące tego, jak klient użytkownika powinien je obsługiwać, producenci przeglądarek mogą wdrożyć, jak uznają za stosowne. Odkryłem, że albo prześlą pierwszy przycisk przesyłania w formularzu, albo prześlą następny przycisk przesyłania po polu formularza, które jest aktualnie aktywne.
Niestety, po prostu dodaje styl wyświetlania: brak; nie będzie działać, ponieważ specyfikacja W3C wskazuje, że jakikolwiek ukryty element powinien być wykluczony z interakcji użytkownika. Zamiast tego ukryj to na widoku!
Powyżej znajduje się przykład rozwiązania, które ostatecznie wprowadziłem do produkcji. Naciśnięcie klawisza Enter powoduje, że domyślne przesłanie formularza jest zgodne z oczekiwaniami, nawet jeśli istnieją inne wartości inne niż domyślne i poprzedzają domyślny przycisk przesyłania w DOM. Premia za interakcję myszy / klawiatury z wyraźnymi danymi wejściowymi użytkownika, przy jednoczesnym unikaniu procedur obsługi javascript.
Uwaga: tabulacja w formularzu nie wyświetli fokusa dla żadnego elementu wizualnego, ale nadal spowoduje wybranie niewidocznego przycisku. Aby uniknąć tego problemu, wystarczy odpowiednio ustawić atrybuty tabindex i pominąć atrybut tabindex na niewidzialnym przycisku przesyłania. Choć może wydawać się nie na miejscu, aby promować te style! Ważne, że należy zapobiec ramowych lub istniejących stylów przycisków zakłócaniu tej poprawki. Te wbudowane style są zdecydowanie kiepską formą, ale sprawdzamy tutaj koncepcje ... nie pisząc kodu produkcyjnego.
źródło
<div style="position: fixed; left: -1000px; top: -1000px />
. Jeszcze jedna sprawa do zmartwienia: minimalizacja lub odsunięcie przycisku od przepływu strony za pomocą CSS może powodować problemy z WAI, ponieważ czytniki ekranu nadal będą widzieć przycisk domyślny.<input/>
tam jest?Myślę, że ten post pomógłby, gdyby ktoś chciał to zrobić za pomocą jQuery:
http://greatwebguy.com/programming/dom/default-html-button-submit-on-enter-with-jquery/
Podstawowym rozwiązaniem jest:
a innym podobało mi się:
źródło
.wich
atrybut. Również nie trzeba wracać do DOM.keyCode
(lub.charCode
w tym przypadku).e.preventDefault();
na początku tej funkcji, aby uniknąć wykonania „prawdziwego” domyślnego przycisku. Działa naprawdę dobrze.Miałem formularz z 11 przyciskami przesyłania i zawsze używałby pierwszego przycisku przesyłania, gdy użytkownik nacisnął klawisz Enter. Czytałem gdzie indziej, że nie jest dobrym pomysłem (zła praktyka), aby mieć więcej niż jeden przycisk wysyłania w formularzu, a najlepszym sposobem na to jest posiadanie przycisku, który chcesz domyślnie, jako jedynego przycisku wysyłania w formularzu. Pozostałe przyciski powinny zostać zmienione na „TYPE = BUTTON” i dodane zdarzenie onClick, które wywołuje własną procedurę przesyłania w Javascript. Coś takiego :-
Tutaj przycisk 3 jest domyślny i chociaż programowo przesyłasz formularz innymi przyciskami, procedura mjsubmit je sprawdza. HTH.
źródło
Można to teraz rozwiązać za pomocą
flexbox
:HTML
CSS
Wyjaśnieniu
Korzystanie z elastycznego okno, możemy odwrócić kolejność elementów w pojemniku, który używa
display: flex
zarówno stosując regułę CSSflex-direction: row-reverse
. Nie wymaga to CSS ani ukrytych elementów. W przypadku starszych przeglądarek, które nie obsługują Flexboksa, nadal mają praktyczne rozwiązanie, ale elementy nie zostaną odwrócone.Demo
http://codepen.io/Godwin/pen/rLVKjm
źródło
Zmagałem się z tym samym pytaniem, ponieważ miałem przycisk „Prześlij” na środku, z którego przekierowałem przesłanie na inną stronę, na przykład:
Gdy użytkownik nacisnął klawisz Enter, ten przycisk został kliknięty zamiast innego przycisku przesyłania.
Zrobiłem więc prymitywne testy, tworząc z wieloma przyciskami przesyłania i różnymi opcjami widoczności oraz powiadamiając o zdarzeniu onclick, który przycisk został kliknięty: https://jsfiddle.net/aqfy51om/1/
Przeglądarki i systemy operacyjne, których użyłem do testowania:
OKNA
OSX
Większość tych przeglądarek kliknęła pierwszy przycisk pomimo zastosowanych opcji widoczności oprócz IE i Safari, które kliknęły trzeci przycisk, który jest „widoczny” w „ukrytym” pojemniku:
Tak więc moją propozycją, której zamierzam użyć, jest:
Jeśli formularz ma wiele przycisków przesyłania o różnym znaczeniu, na początku formularza dołącz przycisk przesyłania z domyślną akcją, który jest albo:
style="width: 0; height: 0; overflow: hidden;"
EDYCJA Inną opcją może być przesunięcie przycisku (wciąż na początku od)
style="position: absolute; left: -9999px; top: -9999px;"
, po prostu wypróbowałem go w IE - działało, ale nie mam pojęcia, co jeszcze może zepsuć, na przykład drukowanie.źródło
Z twoich komentarzy:
Wrzucam
<input type="hidden" value="form_name" />
do każdej formy.W przypadku przesyłania za pomocą javascript: dodaj zdarzenia wysyłania do formularzy, a nie klikaj zdarzeń w ich przyciskach. Użytkownicy Saavy nie dotykają często myszy.
źródło
Jeśli masz wiele przycisków przesyłania w jednym formularzu, a użytkownik naciśnie klawisz ENTER, aby przesłać formularz z pola tekstowego, kod ten zastępuje domyślną funkcjonalność, wywołując zdarzenie Prześlij w formularzu ze zdarzenia naciśnięcia klawisza. Oto ten kod:
źródło
Dziwne, że pierwszy przycisk Enter przechodzi zawsze do pierwszego przycisku, niezależnie od tego, czy jest widoczny, czy nie, np. Przy użyciu jquery
show/hide()
. Dodanie atrybutu.attr('disabled', 'disabled')
uniemożliwia otrzymanie przycisku Enter całkowicie. Jest to problem na przykład podczas dostosowywania widoczności przycisku Wstaw / Edytuj + Usuń w oknach dialogowych zapisu. Znalazłem mniej hackerskie i proste umieszczanie Edytuj przed Inserti użyj kodu javascript:
źródło
mój przepis:
Wyśle domyślne ukryte pole, jeśli żaden z przycisków nie zostanie „kliknięty”.
jeśli zostaną kliknięte, mają preferencje i ich wartość jest przekazywana.
źródło
Innym rozwiązaniem, którego użyłem, jest tylko jeden przycisk w formularzu i fałszywe pozostałe przyciski.
Oto przykład:
Następnie projektuję elementy rozpiętości, aby wyglądały jak przycisk. Odbiornik JS obserwuje zakres i po kliknięciu wykonuje żądaną operację.
Niekoniecznie odpowiednie dla wszystkich sytuacji, ale przynajmniej dość łatwo to zrobić.
źródło
Ze specyfikacji HTML 4 :
Oznacza to, że biorąc pod uwagę więcej niż 1 przycisk przesyłania i żaden aktywowany (kliknięty), żaden nie powinien zakończyć się powodzeniem.
I twierdzę, że ma to sens: wyobraź sobie ogromną formę z wieloma przyciskami wysyłania. U góry znajduje się przycisk „usuń ten rekord”, następnie pojawia się wiele danych wejściowych, a na dole znajduje się przycisk „usuń ten rekord”. Użytkownik uderzający w klawisz Enter, gdy znajduje się w polu u dołu formularza, nigdy nie podejrzewałby, że w sposób dorozumiany uderza „usuń ten rekord” z góry.
Dlatego uważam, że nie jest dobrym pomysłem używanie pierwszego lub innego przycisku, którego użytkownik nie zdefiniuje (nie kliknie). Niemniej jednak przeglądarki to robią.
źródło
EDYCJA: Przepraszam, pisząc tę odpowiedź, myślałem o przesłaniu przycisków w ogólnym znaczeniu. Odpowiedź poniżej nie dotyczy wielu
type="submit"
przycisków, ponieważ pozostawia tylko jedentype="submit"
i zmienia drugi natype="button"
. Zostawiam tutaj odpowiedź jako odniesienie na wypadek, gdyby ktoś mógł zmienićtype
formę:Aby określić, który przycisk zostanie naciśnięty po naciśnięciu klawisza Enter, możesz oznaczyć go
type="submit"
, a pozostałe przyciski -type="button"
. Na przykład:źródło