想知道是否有一个JavaScript没有jQuery或任何允许我序列化窗体和访问序列化版本的框架的函数?窗体序列化javascript(无框架)
回答
这个微型library不依赖于框架。除此之外,您需要自己实现序列化功能。 (虽然在重量的1.2千字节,为什么不使用它?)
function serialize (form) {
if (!form || form.nodeName !== "FORM") {
return;
}
var i, j, q = [];
for (i = form.elements.length - 1; i >= 0; i = i - 1) {
if (form.elements[i].name === "") {
continue;
}
switch (form.elements[i].nodeName) {
case 'INPUT':
switch (form.elements[i].type) {
case 'text':
case 'tel':
case 'email':
case 'hidden':
case 'password':
case 'button':
case 'reset':
case 'submit':
q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
break;
case 'checkbox':
case 'radio':
if (form.elements[i].checked) {
q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
}
break;
}
break;
case 'file':
break;
case 'TEXTAREA':
q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
break;
case 'SELECT':
switch (form.elements[i].type) {
case 'select-one':
q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
break;
case 'select-multiple':
for (j = form.elements[i].options.length - 1; j >= 0; j = j - 1) {
if (form.elements[i].options[j].selected) {
q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].options[j].value));
}
}
break;
}
break;
case 'BUTTON':
switch (form.elements[i].type) {
case 'reset':
case 'submit':
case 'button':
q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
break;
}
break;
}
}
return q.join("&");
}
来源:http://code.google.com/p/form-serialize/source/browse/trunk/serialize-0.1.js
该序列似乎不符合标准形式系列化,其中空格用“+”来表示兼容。上面只使用* encodeURIComponent *,它将空间编码为“%20”。如果需要一致性,最后可以使用正则表达式在传输之前将“%20”转换为“+”。 – RobG
我添加了这样一个修改版本,以https://gist.github.com/brettz9/7147458(与其他一些改进) –
提交按钮,不一定要提交,重置按钮不应该被提交,并且按钮只有在那里用于提交并在这种情况下被视为提交按钮。请参阅[HTML5 4.10.22表单提交](http://www.w3.org/html/wg/drafts/html/CR/forms.html#concept-form-submit)。 – RobG
我开始从Johndave Decano答案。
这应该解决在他的功能回复中提到的一些问题。
- 用%符号替换%20。
- 提交/按钮类型将只被提交,如果他们被点击 提交表格。
- 重置按钮将被忽略。
- 该代码对我来说似乎是多余的,因为它基本上做的是 相同的事情,不管字段类型如何。更不用说 与'tel'和'email'等HTML5字段类型不兼容,因此我使用switch语句删除了大部分细节。
如果按钮类型没有名称值,它仍然会被忽略。
function serialize(form, evt){
var evt = evt || window.event;
evt.target = evt.target || evt.srcElement || null;
var field, query='';
if(typeof form == 'object' && form.nodeName == "FORM"){
for(i=form.elements.length-1; i>=0; i--){
field = form.elements[i];
if(field.name && field.type != 'file' && field.type != 'reset'){
if(field.type == 'select-multiple'){
for(j=form.elements[i].options.length-1; j>=0; j--){
if(field.options[j].selected){
query += '&' + field.name + "=" + encodeURIComponent(field.options[j].value).replace(/%20/g,'+');
}
}
}
else{
if((field.type != 'submit' && field.type != 'button') || evt.target == field){
if((field.type != 'checkbox' && field.type != 'radio') || field.checked){
query += '&' + field.name + "=" + encodeURIComponent(field.value).replace(/%20/g,'+');
}
}
}
}
}
}
return query.substr(1);
}
这就是我目前如何使用这个功能。
<form onsubmit="myAjax('http://example.com/services/email.php', 'POST', serialize(this, event))">
对于重构良好的代码+1。 -1用于忽略禁用的字段,该字段不应出现在查询字符串中。为非常优雅的语句+1,避免重复计算表单元素。总数:+1 :-)谢谢! –
+1 @SimonSteinberger在评论中做数学运算。 –
关于禁用字段的好消息,我最近遇到了一个我正在写的新函数。 +1给你们两个,因为我喜欢阅读有趣的评论。 :) – TibTibs
这里是纯JavaScript的方法:
var form = document.querySelector('form');
var data = new FormData(form);
var req = new XMLHttpRequest();
req.send(data);
虽然它似乎POST请求被唯一的工作。
注意这是IE10及以上而已,但一个很好的解决方案 – John
注意,这发出多,这与一些简单的REST服务(即羽毛-的MongoDB) –
我完全忘了这个不好的作品,我很高兴你张贴在这里。谢谢 – jaggedsoft
这里的TibTibs略加修改版本:
function serialize(form) {
var field, s = [];
if (typeof form == 'object' && form.nodeName == "FORM") {
var len = form.elements.length;
for (i=0; i<len; i++) {
field = form.elements[i];
if (field.name && !field.disabled && field.type != 'file' && field.type != 'reset' && field.type != 'submit' && field.type != 'button') {
if (field.type == 'select-multiple') {
for (j=form.elements[i].options.length-1; j>=0; j--) {
if(field.options[j].selected)
s[s.length] = encodeURIComponent(field.name) + "=" + encodeURIComponent(field.options[j].value);
}
} else if ((field.type != 'checkbox' && field.type != 'radio') || field.checked) {
s[s.length] = encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value);
}
}
}
}
return s.join('&').replace(/%20/g, '+');
}
残疾人字段将被丢弃和名称也是URL编码。在返回字符串之前,正则表达式替换%20个字符只发生一次。
查询字符串与jQuery的$ .serialize()方法的结果形式相同。
如果您想要序列化事件上的输入。这是我使用的纯JavaScript方法。
// serialize form
var data = {};
var inputs = [].slice.call(e.target.getElementsByTagName('input'));
inputs.forEach(input => {
data[input.name] = input.value;
});
数据将是输入的JavaScript对象。
这应该对大多数元素,绝对不是文本区域/选择工作,虽然 – jaggedsoft
是slice.call一样Array.from? – user1040495
一个使用更少的变量,并采取forEach
循环的速度优势(这是有点快于for
S)
function serialize(form) {
var result = [];
if (typeof form === 'object' && form.nodeName === 'FORM')
Array.prototype.slice.call(form.elements).forEach(function(control) {
if (
control.name &&
!control.disabled &&
['file', 'reset', 'submit', 'button'].indexOf(control.type) === -1
)
if (control.type === 'select-multiple')
Array.prototype.slice.call(control.options).forEach(function(option) {
if (option.selected)
result.push(encodeURIComponent(control.name) + '=' + encodeURIComponent(option.value));
});
else if (
['checkbox', 'radio'].indexOf(control.type) === -1 ||
control.checked
) result.push(encodeURIComponent(control.name) + '=' + encodeURIComponent(control.value));
});
return result.join('&').replace(/%20/g, '+');
}
我重构TibTibs回答到的东西,是更清晰,以重构的@ SimonSteinberger的代码版本读。由于80个字符的宽度和一些注释,它有点长。
此外,它会忽略空白字段名称和空白值。
// Serialize the specified form into a query string.
//
// Returns a blank string if +form+ is not actually a form element.
function $serialize(form, evt) {
if(typeof(form) !== 'object' && form.nodeName !== "FORM")
return '';
var evt = evt || window.event || { target: null };
evt.target = evt.target || evt.srcElement || null;
var field, query = '';
// Transform a form field into a query-string-friendly
// serialized form.
//
// [NOTE]: Replaces blank spaces from its standard '%20' representation
// into the non-standard (though widely used) '+'.
var encode = function(field, name) {
if (field.disabled) return '';
return '&' + (name || field.name) + '=' +
encodeURIComponent(field.value).replace(/%20/g,'+');
}
// Fields without names can't be serialized.
var hasName = function(el) {
return (el.name && el.name.length > 0)
}
// Ignore the usual suspects: file inputs, reset buttons,
// buttons that did not submit the form and unchecked
// radio buttons and checkboxes.
var ignorableField = function(el, evt) {
return ((el.type == 'file' || el.type == 'reset')
|| ((el.type == 'submit' || el.type == 'button') && evt.target != el)
|| ((el.type == 'checkbox' || el.type == 'radio') && !el.checked))
}
var parseMultiSelect = function(field) {
var q = '';
for (var j=field.options.length-1; j>=0; j--) {
if (field.options[j].selected) {
q += encode(field.options[j], field.name);
}
}
return q;
};
for(i = form.elements.length - 1; i >= 0; i--) {
field = form.elements[i];
if (!hasName(field) || field.value == '' || ignorableField(field, evt))
continue;
query += (field.type == 'select-multiple') ? parseMultiSelect(field)
: encode(field);
}
return (query.length == 0) ? '' : query.substr(1);
}
我复制此直接进入我的应用程序和多选不出现工作(该值重复) – anastymous
@anastymous感谢您的接触,它已被修复。 –
嗨,布赖恩,什么是** evt **?我应该通过什么呢? Firefox告诉我它没有被定义。 – anastymous
HTMLElement.prototype.serialize = function(){
var obj = {};
var elements = this.querySelectorAll("input, select, textarea");
for(var i = 0; i < elements.length; ++i) {
var element = elements[i];
var name = element.name;
var value = element.value;
if(name) {
obj[ name ] = value;
}
}
return JSON.stringify(obj);
}
要使用这样的:
var dataToSend = document.querySelector("form").serialize();
我希望我帮助。
上混淆了此行为的一个非常基本的示例。将无法使用复选框。在这里,您必须明确检查输入类型。 –
如果你的目标是支持URLSearchParams
API(all recent browsers)浏览器,使用:否则
new URLSearchParams(new FormData(formElement)).toString()
,用这一个班轮(作品无处不在,除了IE):
如果您需要使用JSON格式的POST提交表单“myForm”,你可以这样做:
const formEntries = new FormData(myForm).entries();
const json = Object.assign(...Array.from(formEntries, ([x,y]) => ({[x]:y})));
fetch('/api/foo', {
method: 'POST',
body: JSON.stringify(json)
});
第二行从数组转换等:
[["firstProp", "firstValue"], ["secondProp", "secondValue"], ...and so on... ]
...到常规目的,如:
{"firstProp": "firstValue", "secondProp": "secondValue", ...and so on ... }
...它通过传递mapFn成Array.from执行此转换()。这个mapFn应用于每个[“a”,“b”]对,并将它们转换为{“a”:“b”},以便数组包含很多对象,每个对象只有一个属性。 mapFn使用“解构”来获取对的第一部分和第二部分的名称,并且它还使用ES6“ComputedPropertyName”来设置由mapFn返回的对象中的属性名称(这就是为什么说“然后将所有这些单个属性对象传递到Object.assign()函数的参数中,该函数将所有单个属性对象合并成一个单独的对象,该对象具有所有属性
Array.from(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
解构在参数: https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/
更多关于计算的属性名称的位置: Variable as the property name in a JavaScript object literal?
// supports IE8 and IE9
function serialize(form) {
var inputs = form.elements;
var array = [];
for(i=0; i < inputs.length; i++) {
var inputNameValue = inputs[i].name + '=' + inputs[i].value;
array.push(inputNameValue);
}
return array.join('&');
}
//using the serialize function written above
var form = document.getElementById("form");//get the id of your form. i am assuming the id to be named form.
var form_data = serialize(form);
var xhr = new XMLHttpRequest();
xhr.send(form_data);
//does not work with IE8 AND IE9
var form = document.querySelector('form');
var data = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.send(data);
我从@moison答案,从MDN抢过项()FORMDATA的方法,它是说:
的FORMDATA 。entries()方法返回一个迭代器,允许通过包含在此对象中的所有键/值对去执行 。每个 对的关键是一个USVString对象;该值可以是USVString或Blob。
但唯一的问题是,手机浏览器(Android和Safari浏览器不支持)和IE和Safari桌面过于
但基本上这里是我的方法:
let theForm = document.getElementById("contact");
theForm.onsubmit = function(event) {
event.preventDefault();
let rawData = new FormData(theForm);
let data = {};
for(let pair of rawData.entries()) {
data[pair[0]] = pair[1];
}
let contactData = JSON.stringify(data);
console.warn(contactData);
//here you can send a post request with content-type :'application.json'
};
码即可发现here
document.serializeForm = function (selector) {
var dictionary = {};
var form = document.querySelector(selector);
var formdata = new FormData(form);
var done = false;
var iterator = formdata.entries();
do {
var prop = iterator.next();
if (prop.done && !prop.value) {
done = true;
}
else {
dictionary[prop.value[0]] = prop.value[1];
}
} while (!done);
return dictionary;
}
- 1. 实体框架(实体类)序列化
- 2. 实体框架序列化错误
- 3. 实体框架POCO序列化
- 4. 序列化和反序列化实体框架版本
- 5. IOS窗体框架
- 6. 窗体序列化问题
- 7. 数据序列化框架
- 8. 实体框架:在场景后面序列化/反序列化JSON列
- 9. WCF - 实体框架,生成的实体序列化错误
- 10. Django Rest框架序列化器作为窗体和嵌套关系
- 11. 实体框架序列化到一列的多个属性
- 12. 使用Visual Studio实体框架&C序列化/反序列化SQLite数据库#
- 13. 尝试序列化实体框架对象时出现XML序列化错误
- 14. Objective-C窗体框架
- 15. Zend框架:在窗体类
- 16. zend框架子窗体isValidPartial?
- 17. Zend框架调用窗体作为窗体内的子窗体
- 18. SqlException:无效的列名(实体框架)
- 19. 实体框架4.1无效列名
- 20. 实体框架:无效的列名称
- 21. 实体框架5无效的列名
- 22. 实体框架无效的列名'Model_Key'
- 23. 实体框架无效的列名称
- 24. 实体框架:无效的列名'OrganizationStructure_ID'
- 25. 实体框架Fluent API:IndexAnnotationSerializer无法序列化'IndexAttribute'类型的对象。
- 26. 实体框架将POCO序列化为JSON
- 27. 如何避免循环引用,而序列化实体框架
- 28. 从实体框架类生成可序列化的类?
- 29. 实体框架和序列化/远程数据访问
- 30. json.net;序列化实体框架对象(循环引用错误)
要回答这个问题,没有。 – RobG
“访问序列化版本”是什么意思?我已经开发了有没有第三方的依赖,可以在HTML格式转换成像对象JSON是多维的脚本:https://github.com/serbanghita/formToObject - 如果它有助于降回复 –