技术问询:无表单包裹的双隐藏表单JSON序列化及IE兼容问题
解决无form/fieldset场景下的输入转JSON问题(兼容IE)
嘿,我懂你遇到的这个糟心情况——没法用form或fieldset标签,之前靠form.elements生成JSON的路子在IE上走不通了。别慌,咱们换个思路,直接手动遍历目标容器里的输入元素来构建JSON,完美避开兼容性坑!
核心思路
既然不能依赖elements属性,那我们就直接抓取目标div下的所有输入类元素(input、textarea、select都覆盖到),然后逐个处理它们的值,最终拼成符合要求的JSON对象。
第一步:灵活获取所有输入元素
你之前用的getElementsByTagName('input')没问题,但可以扩展得更全面一点,比如用querySelectorAll(IE8及以上都支持,要是得兼容更老的IE,后面我会给替代方案):
// 抓取formularEins容器下所有输入、文本域、下拉框元素 const inputElements = document.getElementById('formularEins').querySelectorAll('input, textarea, select');
第二步:遍历元素构建JSON
这里要注意不同类型输入的特殊处理,比如复选框是多值、单选框只取选中项,别一股脑直接拿value:
function convertInputsToJson(containerId) { const result = {}; const elements = document.getElementById(containerId).querySelectorAll('input, textarea, select'); // 遍历所有元素,IE下如果forEach不支持,就换成for循环 Array.prototype.forEach.call(elements, function(el) { // 跳过没有name属性的元素,避免无效数据 if (!el.name) return; // 处理复选框:同name的复选框存为数组,只收集选中的 if (el.type === 'checkbox') { if (!result[el.name]) { result[el.name] = []; } if (el.checked) { result[el.name].push(el.value || 'on'); // 没设value的复选框默认值是'on' } return; } // 处理单选框:只保留选中的那个的值 if (el.type === 'radio') { if (el.checked) { result[el.name] = el.value; } return; } // 普通输入、文本域、下拉框直接取value result[el.name] = el.value; }); return JSON.stringify(result); }
第三步:结合你的场景调用方法
比如点击按钮显示表单,提交时生成JSON并发送请求:
// 点击按钮显示第一个表单 document.getElementById('showForm1Btn').onclick = function() { document.getElementById('formularEins').style.display = 'block'; }; // 提交表单时生成JSON并发送请求 document.getElementById('submitForm1Btn').onclick = function() { const jsonStr = convertInputsToJson('formularEins'); // 用XMLHttpRequest发送请求(兼容IE),要是用fetch记得加polyfill const xhr = new XMLHttpRequest(); xhr.open('POST', '/your-target-url', true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(jsonStr); };
兼容更老IE的补充方案
如果要兼容IE7及更早版本,querySelectorAll不支持,那就换成getElementsByTagName来分别获取不同类型的元素,再合并成数组:
function convertInputsToJson(containerId) { const result = {}; const container = document.getElementById(containerId); // 分别获取各类元素 const inputs = container.getElementsByTagName('input'); const textareas = container.getElementsByTagName('textarea'); const selects = container.getElementsByTagName('select'); // 把类数组转成数组(IE下用slice.call) const allElements = Array.prototype.slice.call(inputs) .concat(Array.prototype.slice.call(textareas)) .concat(Array.prototype.slice.call(selects)); // 用for循环遍历(IE7不支持forEach) for (let i = 0; i < allElements.length; i++) { const el = allElements[i]; // 下面的处理逻辑和之前一致,此处省略重复代码 if (!el.name) continue; if (el.type === 'checkbox') { if (!result[el.name]) result[el.name] = []; if (el.checked) result[el.name].push(el.value || 'on'); continue; } if (el.type === 'radio') { if (el.checked) result[el.name] = el.value; continue; } result[el.name] = el.value; } return JSON.stringify(result); }
这样一来,不管有没有form/fieldset标签,也不管是现代浏览器还是IE,都能稳稳地把输入内容转成JSON啦!
内容的提问来源于stack exchange,提问作者chris
相关产品推荐
相关产品推荐

