You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:14:59