[javascript] HTML 양식의 기본 제출 버튼은 어떻게 결정됩니까?

양식이 제출되었지만 다음과 같은 특정 버튼으로 제출되지 않은 경우

  • 눌러 Enter
  • HTMLFormElement.submit()JS에서 사용

브라우저는 여러 개의 제출 단추 중 하나를 눌렀을 때 사용할 단추를 어떻게 결정해야합니까?

이것은 두 가지 수준에서 중요합니다.

  • onclick제출 단추에 첨부 된 이벤트 핸들러 호출
  • 웹 서버로 다시 전송 된 데이터

지금까지의 실험 결과는 다음과 같습니다.

  • Enter, Firefox, Opera 및 Safari를 누를 때 양식의 첫 번째 제출 단추를 사용하십시오.
  • 를 누르면 EnterIE는 첫 번째 제출 버튼을 사용하거나 알아낼 수없는 조건에 따라 전혀 사용하지 않습니다.
  • 이 모든 브라우저는 JS 제출에 전혀 사용하지 않습니다.

표준은 무엇을 말합니까?

도움이된다면 여기에 내 테스트 코드가 있습니다 (PHP는 내 질문 자체가 아닌 테스트 방법에만 관련이 있습니다)

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



답변

당신은 자바 스크립트 (예를 통해 양식을 제출하는 경우 formElement.submit()또는 아무것도에 해당), 다음 아무도 의이 버튼을 성공적으로 간주되며 그 값이 하나도 제출 된 데이터에 포함되지 않습니다 제출하지 않습니다. (이를 사용하여 양식을 제출하면 submitElement.click()참조가있는 제출이 활성화 된 것으로 간주됩니다. 제출 버튼이 모호하지 않기 때문에 실제로 귀하의 질문에 해당되지는 않습니다.하지만 포함시킬 것이라고 생각했습니다. 첫 번째 부분을 읽고 JS 양식 제출을 통해 제출 버튼을 성공적으로 만드는 방법을 궁금해하는 사람들을 위해. 물론 양식의 onsubmit 핸들러는 여전히 이런 식으로 실행되지만 반면 form.submit()에 물고기의 다른 주전자 는 아닙니다 .)

텍스트가 아닌 필드에서 Enter 키를 눌러 양식을 제출하면 실제로는 사용자 에이전트가 원하는 것을 결정합니다. 사양 (다음 명확하게 사용되는 특정 제출 버튼으로 아무 문제가 없다, 만약 당신이 탭 버튼에 공간 또는 무엇이든을 사용하여 활성화)를 텍스트 입력 필드에 키 동안 입력 사용하여 양식 제출에 대한 아무 말도하지 않습니다. 제출 버튼이 활성화 될 때 양식을 제출해야한다는 것은 텍스트 입력과 같이 Enter 키를 누르는 것만으로도 양식을 제출할 필요는 없습니다.

Internet Explorer는 소스에서 첫 번째로 나타나는 제출 단추를 선택한다고 생각합니다. Firefox와 Opera는 tabindex가 가장 낮은 버튼을 선택하고 다른 것이 정의되어 있지 않으면 처음으로 정의 된 것으로 되돌아갑니다. 제출에 기본값이 아닌 속성 IIRC가 있는지 여부와 관련하여 몇 가지 복잡한 문제가 있습니다.

여기서 해결해야 할 점은 여기서 일어나는 일에 대한 정의 된 표준이 없으며, 전적으로 브라우저의 책임에 달려 있다는 것입니다. 가능한 모든 작업에서 가능한 한 특정 행동에 의존하지 않도록하십시오. 정말로 알아야 할 경우 다양한 브라우저 버전의 동작을 찾을 수 있지만 잠시 후 다시 조사했을 때 상당히 복잡한 조건이 있었으며 (물론 새 브라우저 버전으로 변경 될 수 있음) 조언합니다. 가능하면 피하십시오!


답변

HTML 4는 그것을 명시 적으로 만들지 않습니다. 현재 HTML5 작업 초안 은 첫 번째 제출 단추가 기본값이어야 함을 지정합니다 .

form요소의 기본 버튼은 첫 번째 단추를 제출
나무 위해서는형태 소유자
form요소입니다.

사용자 에이전트가 사용자가 양식을 암시 적으로 제출할 수 있도록 지원하는 경우 (예를 들어, 텍스트 필드에 포커스가있는 동안 “enter”키를 누르는 양식이 암시 적으로 양식을 제출하는 경우) 기본 단추활성화
양식이있는 양식에 대해 수행 이 동작으로 인해 사용자 에이전트 는 해당 기본 버튼 에서
합성 클릭 활성화 단계실행 해야
합니다 .


답변

Andrezj는 거의 문제가 없었지만 여기에 쉬운 크로스 브라우저 솔루션이 있습니다.

다음과 같은 양식을 작성하십시오.

<form>
    <input/>
    <button type="submit" value="some non-default action"/>
    <button type="submit" value="another non-default action"/>
    <button type="submit" value="yet another non-default action"/>

    <button type="submit" value="default action"/>
</form>

그리고 이것을 리팩토링하십시오 :

<form>
    <input/>

    <button style="overflow: visible !important; height: 0 !important; width: 0 !important; margin: 0 !important; border: 0 !important; padding: 0 !important; display: block !important;" type="submit" value="default action"/>

    <button type="submit" value="some non-default action"/>
    <button type="submit" value="another non-default action"/>
    <button type="submit" value="yet another non-default action"/>
    <button type="submit" value="still another non-default action"/>

    <button type="submit" value="default action"/>
</form>

W3C 사양에는 여러 제출 단추가 유효하지만 사용자 에이전트가 처리해야하는 방법에 대한 지침은 생략되어 있으므로 브라우저 제조업체는 적절한대로 구현해야합니다. 양식에 첫 번째 제출 버튼을 제출하거나 현재 포커스가있는 양식 필드 다음에 다음 제출 버튼을 제출하는 것으로 나타났습니다.

불행히도 단순히 표시 스타일을 추가하는 것 : none; W3C 사양은 숨겨진 요소가 사용자 상호 작용에서 제외되어야 함을 나타내므로 작동하지 않습니다. 그래서 대신에 그것을 평범한 곳에 숨기십시오!

위는 제가 생산에 투입 한 솔루션의 예입니다. Enter 키를 누르면 기본값 이외의 다른 값이 존재하고 DOM의 기본 제출 단추 앞에있는 경우에도 기본 양식 제출이 예상대로 작동합니다. 자바 스크립트 핸들러를 피하면서 명시적인 사용자 입력과 마우스 / 키보드 상호 작용에 대한 보너스.

참고 : 양식을 탭하면 시각적 요소에 대한 초점이 표시되지 않지만 여전히 보이지 않는 버튼이 선택됩니다. 이 문제를 피하려면 간단히 tabindex 속성을 설정하고 보이지 않는 제출 단추에서 tabindex 속성을 생략하십시오. 이러한 스타일을 중요로 승격시키는 것이 적절하지 않은 것처럼 보일 수 있지만 프레임 워크 또는 기존 버튼 스타일이이 수정을 방해하지 않아야합니다 . 또한 인라인 스타일은 형식이 좋지 않지만 프로덕션 코드를 작성하지 않고 개념을 입증하고 있습니다.


답변

누군가가 jQuery로 그것을 원한다면이 게시물이 도움이 될 것이라고 생각합니다.

http://greatwebguy.com/programming/dom/default-html-button-submit-on-enter-with-jquery/

기본 솔루션은 다음과 같습니다.

$(function() {
    $("form input").keypress(function (e) {
    if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
        $('input[type=submit].default').click();
        return false;
    } else {
        return true;
    }
    });
});

그리고 내가 좋아하는 또 다른 것은 :

jQuery(document).ready(function() {
$("form input, form select").live('keypress', function (e) {
if ($(this).parents('form').find('button[type=submit].default, input[type=submit].default').length <= 0)
return true;

if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
$(this).parents('form').find('button[type=submit].default, input[type=submit].default').click();
return false;
} else {
return true;
}
});
}); 


답변

11 개의 제출 버튼이있는 양식이 있었고 사용자가 Enter 키를 누를 때 항상 첫 번째 제출 버튼을 사용합니다. 다른 곳에서 폼에 제출 단추를 두 개 이상 갖는 것은 좋지 않은 아이디어 (나쁜 습관)가 아니며 이것을 수행하는 가장 좋은 방법은 폼의 유일한 제출 단추와 같이 기본적으로 원하는 단추를 사용하는 것입니다. 다른 버튼은 “TYPE = BUTTON”으로 만들어야하고 Javascript에서 자체 제출 루틴을 호출하는 onClick 이벤트가 추가되어야합니다. 이 같은 :-

<SCRIPT Language="JavaScript">
function validform()
{
  // do whatever you need to validate the form, and return true or false accordingly
}

function mjsubmit()
{
  if (validform()) { document.form1.submit(); return true;}
  return false;
}
</SCRIPT>
<INPUT TYPE=BUTTON NAME="button1" VALUE="button1" onClick="document.form1.submitvalue='button1'; return mjsubmit();">
<INPUT TYPE=BUTTON NAME="button2" VALUE="button2" onClick="document.form1.submitvalue='button2'; return mjsubmit();">
<INPUT TYPE=SUBMIT NAME="button3" VALUE="button3" onClick="document.form1.submitvalue='button3'; return validform();">
<INPUT TYPE=BUTTON NAME="button4" VALUE="button4" onClick="document.form1.submitvalue='button4'; return mjsubmit();">

여기서는 button3이 기본값이며 다른 버튼으로 프로그래밍 방식으로 양식을 제출하더라도 mjsubmit 루틴이이를 검증합니다. HTH.


답변

이제 다음을 사용하여 해결할 수 있습니다 flexbox.

HTML

<form>
    <h1>My Form</h1>
    <label for="text">Input:</label>
    <input type="text" name="text" id="text"/>

    <!-- Put the elements in reverse order -->
    <div class="form-actions">
        <button>Ok</button> <!-- our default action is first -->
        <button>Cancel</button>
    </div>
</form>

CSS

.form-actions {
    display: flex;
    flex-direction: row-reverse; /* reverse the elements inside */
}

설명
flex 상자 display: flex를 사용하면 CSS 규칙을 사용하여 사용하는 컨테이너의 요소 순서를 반대로 바꿀 수 있습니다 flex-direction: row-reverse. CSS 나 숨겨진 요소가 필요하지 않습니다. flexbox를 지원하지 않는 구형 브라우저의 경우 여전히 실행 가능한 솔루션을 얻지 만 요소는 바뀌지 않습니다.

데모
http://codepen.io/Godwin/pen/rLVKjm


답변

다른 페이지로 제출을 리디렉션 한 중간에 제출 버튼이 있었기 때문에 같은 질문으로 고생했습니다.

<button type="submit" onclick="this.form.action = '#another_page'">More</button>

사용자가 Enter 키를 누르면 다른 제출 단추 대신이 단추가 클릭되었습니다.

그래서 여러 제출 버튼과 다른 가시성 옵션을 사용하여 from을 작성하고 어떤 버튼을 클릭했는지 onclick 이벤트 경고를 작성하여 기본 테스트를 수행했습니다. https://jsfiddle.net/aqfy51om/1/

테스트에 사용한 브라우저 및 OS :

WINDOWS

  • 구글 크롬 43 (c’mon google : D)
  • 모질라 파이어 폭스 38
  • 인터넷 익스플로러 11
  • 오페라 30.0

OSX

  • 구글 크롬 43
  • 사파리 7.1.6

이 브라우저의 대부분은 “숨겨진”컨테이너 안에 “표시”되는 세 번째 버튼을 클릭 한 IE 및 Safari 실행 옵션이 적용된 가시성 옵션에도 불구하고 첫 번째 버튼 을 클릭했습니다.

<div style="width: 0; height: 0; overflow: hidden;">
    <button type="submit" class="btn btn-default" onclick="alert('Hidden submit button #3 was clicked');">Hidden submit button #3</button>
</div>

그래서 내가 사용하려고하는 내 제안은 다음과 같습니다.

양식에 다른 의미의 제출 단추가 여러 개있는 경우 양식 시작 부분에 기본 조치가있는 제출 단추를 포함 시키십시오.

  1. 완전히 보이는
  2. 용기에 싸서 style="width: 0; height: 0; overflow: hidden;"

편집
또 다른 옵션은 버튼을 오프셋하는 것입니다 (여전히 from의 시작 부분) style="position: absolute; left: -9999px; top: -9999px;", IE에서 작동했지만 시도해 볼 수 있습니다.