jQuery Mobile加载器在Firefox中失效 带文件上传的表单提交时Chrome正常显示
故障根因
- 选择器匹配错误:JS绑定提交事件的目标是
#sw-update,但实际表单的ID是#sw-update-form,存在基础的选择器不匹配问题。 - 浏览器渲染调度差异:原生表单提交触发时,Firefox会立刻挂起页面渲染进程准备执行上传/跳转,jQuery Mobile插入的加载器DOM还未完成绘制就被进程挂起,因此无法被肉眼观察到。Chrome的渲染优先级不同,会先完成加载器的绘制流程,再触发提交动作,因此表现正常。
- 连续点击两次提交才显示加载器的现象,正是上述差异导致:第一次提交时加载器DOM刚插入就被挂起,未完成绘制;第二次点击时DOM已经存在于渲染树中,才会被正常显示。
修正方案
不需要改动现有HTML结构,也不需要破坏原有的文件上传能力,全程保留表单原有的data-ajax="false"属性,避免触发jQuery Mobile默认的AJAX提交导致文件上传失败。具体操作:
- 把事件绑定的选择器修正为实际的表单ID
- 提交时先暂时阻断原生的同步提交流程,展示加载器后给浏览器留出一小段渲染时间,等加载器完全绘制完成后,再触发原生的表单提交,不改变原有上传接口的请求格式。
可直接复用的代码
原有HTML保持不变即可:
<form id="sw-update-form" name="multipart" action="/upload" data-ajax="false" method="post" enctype="multipart/form-data"> <fieldset data-role="controlgroup"> <label id="ss1_l"> <input type="radio" name="update" value="fs1">Update filesystem 1 </label> <label id="ss2_l"> <input type="radio" name="update" value="fs2">Update filesystem 2 </label> <label for="file">Selected file:</label> <input type="file" name="file" id="file" /> <input type="submit" name="upload" value="Update" /> </fieldset> </form>
修正后的JS逻辑:
$(document).on("pagecreate", "#page1", function() { // 修正选择器为实际的表单ID $(document).on('submit', '#sw-update-form', function (e) { // 先阻断同步的原生提交,避免进程立刻挂起渲染 e.preventDefault(); const currentForm = this; // 触发jQuery Mobile加载器展示 $.mobile.loading("show", { text: "Updating", textVisible: true, theme: "b", textonly: false, html: `<h1><img src="../images/ajax-loader.gif"></h1><h1>Updating</h1>` }); // 留30ms渲染窗口,等加载器完全绘制后再触发原生提交 setTimeout(() => { currentForm.submit(); }, 30); }); });
此前操作踩坑的原因说明
- 使用ajax.post无法传文件:原生jQuery的POST请求默认不会自动序列化文件输入框的二进制内容,需要手动构建FormData对象,额外开发成本高,没必要放弃成熟的原生表单提交逻辑。
- 移除
data-ajax="false"导致提交失效:这个属性的作用是告知jQuery Mobile不要拦截表单转AJAX提交,移除后框架会把原生表单转成AJAX请求,本身不兼容文件字段的上传逻辑,自然会运行失败。 - 调用preventDefault后重新触发提交却无法展示加载器:本质是没有给浏览器留足够的渲染时间,加载器DOM刚插入就被提交动作挂起进程,Firefox下就看不到视觉效果。
内容的提问来源于stack exchange,提问作者ikki_fenix
相关产品推荐
相关产品推荐

