Siempre he creído que el comportamiento predeterminado de presionar la tecla 'Retorno' era enviar el formulario. Pero parece ser más complejo: si hay un botón cercano, la tecla 'Retorno' parece simular un evento de 'clic' en ese botón, en lugar de enviar el formulario. Aquí hay un ejemplo:
document.querySelector('form').onsubmit = ev => { ev.preventDefault(); document.querySelector('#result').innerText = ev.target.elements.text.value; }; document.querySelector('#troublesome').onclick = ev => { ev.preventDefault(); ev.target.innerText = Math.random(); }; <form> <input type="text" name='text' value='something' /> <button id="troublesome">Trouble</button> <button>Submit</button> </form> <div id="result">not submitted</div> Arriba, cuando presiona regresar en el elemento <input> , el navegador elige hacer clic en el botón "Problemático". ¿Pero por qué? ¿Qué está pasando exactamente aquí? ¿Y dónde puedo leerlo en las especificaciones?
Ambos elementos de botón no tienen ningún conjunto de tipos. Type=submit "es el valor predeterminado si el atributo no se especifica para los botones asociados con un <form> " ( MDN Webdocs ) y problemático es el siguiente después del campo de entrada. Si cambia su tipo a 'botón', se enviará 'enviar'.
De MDN también: "Tenga en cuenta que el evento de envío se activa en el elemento en sí, y no en ninguno o dentro de él. Sin embargo, el Evento de envío que se envía para indicar que se ha activado la acción de envío del formulario, incluye una propiedad de remitente, que es el que se invocó para activar la solicitud de envío. Si el envío no fue activado por un botón de algún tipo, el valor de remitente es nulo. (Si no hay ningún tipo de elemento = enviar y se presiona Intro dentro de la entrada, el formulario se enviará con event.submitter = null)
La lógica parece ser "buscar el botón más cercano al enfoque que tiene type="submit", y simular un evento de clic en ese botón, de lo contrario, simplemente envíe el formulario" (no encontré esto explícitamente en alguna parte) En su el ejemplo 'problemático' es del tipo 'enviar' y más cercano a la entrada, y si no hubiera 'prevenir.default()', se activarían ambos eventos (hacer clic y enviar).
document.querySelector('form').onsubmit = ev => { ev.preventDefault(); document.querySelector('#result').innerText = ev.target.elements.text.value; }; document.querySelector('#troublesome').onclick = ev => { ev.preventDefault(); ev.target.innerText = Math.random(); }; <form> <input type="text" name='text' value='something' /> <button type="button" id="troublesome">Trouble</button> <button>Submit</button> </form> <div id="result">not submitted</div>