iOS端JS中Event.preventDefault()阻止表单提交失效求助
iOS 表单提交阻止默认行为失效问题
问题现象
iOS设备上,表单提交时e.preventDefault()无法阻止页面跳转,POST请求后页面直接跳转到目标URL并显示返回的JSON数据;但该功能在PC和安卓设备上完全正常。
另外发现:若表单仅保留提交按钮、无任何输入字段时,功能恢复正常。
相关代码
JavaScript 逻辑
document.addEventListener("DOMContentLoaded", function () { const individualOrderForm = document.getElementById('individual-order-form'); async function sendAjax(form) { try { const response = await fetch(form.action, { method: 'POST', body: new FormData(form) }); const data = await response.json(); if (data.status === "success") { showToast(data.detail, "success"); disableForm(form); } else { let errors = JSON.parse(data.errors); let errorsText = Object.entries(errors) .map(([field, errors]) => { return errors.map(error => `${error.message}`).join('\n'); }) .join('\n'); showToast(`${data.detail}\n${errorsText}`, "danger"); } } catch (error) { console.log(error); showToast(gettext("Произошла ошибка. Повторите попытку позже."), "danger"); } } individualOrderForm.addEventListener( 'submit', function (e) { e.preventDefault(); sendAjax(individualOrderForm); }, {passive: false} ); });
HTML 表单代码
<form id="individual-order-form" action="{% url 'mainpage:individual-order-negotiate' %}" method="POST" class="d-flex w-100 flex-column justify-content-start align-items-start text-start card-body"> <fieldset class="w-100"> <legend class="text-center"> <h2 class="fs-4 fw-normal" id="contact-us"> {% translate 'Свяжитесь с нами' %} </h2> </legend> <div class="form-text">{% translate 'Заполните форму, чтобы заказать букет из индивидуального состава.' %}</div> {% csrf_token %} <div class="mb-3 w-100"> <label for="customerNameInput" class="form-label">{% translate 'Имя' %}</label> <input class="form-control text-start" id="customerNameInput" aria-describedby="nameHelp" name="first_name" required> </div> <div class="mb-3"> <label for="contact-method-input" class="form-label"> {% translate 'Тел. номер в любой соц. сети или ссылка профиля' %} </label> <div class="d-flex"> {{ individual_order_form.contact_method }} </div> </div> <div class="mb-3 form-check"> <input type="checkbox" class="form-check-input checkbox-dark" id="recallCheckbox" name="recall_me"> <label class="form-check-label" for="recallCheckbox"> <small> {% translate 'Разрешаю мне перезвонить' %} </small> </label> </div> <button class="btn btn-dark-green">{% translate 'Связаться' %}</button> </fieldset> </form>
已尝试的无效操作
- 清除客户端及服务器端缓存
- 执行
manage.py collectstatic - 重启服务器
- 参考移动端事件处理相关方案
解决方案建议
1. 移除passive配置参数
iOS Safari对表单提交事件的passive属性处理存在兼容性问题,直接移除该配置:
individualOrderForm.addEventListener('submit', function (e) { e.preventDefault(); sendAjax(individualOrderForm); });
2. 显式指定按钮type="submit"
表单内按钮默认type为submit,但显式声明可避免iOS浏览器识别异常:
<button type="submit" class="btn btn-dark-green">{% translate 'Связаться' %}</button>
3. 手动拦截表单验证流程
iOS Safari可能在表单验证未通过时绕过自定义事件处理,手动触发验证并拦截:
individualOrderForm.addEventListener('submit', function (e) { if (!individualOrderForm.checkValidity()) { e.preventDefault(); individualOrderForm.reportValidity(); return; } e.preventDefault(); sendAjax(individualOrderForm); });
4. 改用事件委托绑定
如果直接绑定失效,尝试将事件绑定到document层面:
document.addEventListener('submit', function(e) { const targetForm = e.target; if (targetForm.id === 'individual-order-form') { e.preventDefault(); sendAjax(targetForm); } });
5. 调整脚本加载时机
确保JS脚本在DOM完全渲染后执行,可将脚本放在</body>标签前,或给脚本添加defer属性:
<script src="your-script.js" defer></script>
内容的提问来源于stack exchange,提问作者Levinson
相关产品推荐
相关产品推荐

