形式串行化的JavaScript(没有框架)(form serialize javascript (

2019-06-17 12:51发布

想知道有没有在JavaScript函数没有jQuery的或,让我来序列化形式和访问的序列化版本的任何框架?

Answer 1:

微型从序列化库不依赖于一个框架。 除了类似的东西,你需要自己实现序列化功能。 (虽然在重量的1.2千字节,为什么不能用呢?)



Answer 2:

这里是纯JavaScript的方法:

var form = document.querySelector('form');
var data = new FormData(form);
var req = new XMLHttpRequest();
req.send(data);

虽然它似乎是POST请求被唯一的工作。

https://developer.mozilla.org/en-US/docs/Web/API/FormData



Answer 3:

对于现代的浏览器只

如果你的目标是支持的浏览器URLSearchParams API( 最新的浏览器 )和FormData(formElement)构造函数( 最新的浏览器 除边沿 ),使用此:

new URLSearchParams(new FormData(formElement)).toString()

各地,除了IE

对于支持的浏览器URLSearchParams但不是FormData(formElement)构造,使用这种FORMDATA填充工具和代码(作品无处不在IE除外):

new URLSearchParams(Array.from(new FormData(formElement))).toString()

 var form = document.querySelector('form'); var out = document.querySelector('output'); function updateResult() { try { out.textContent = new URLSearchParams(Array.from(new FormData(form))); out.className = ''; } catch (e) { out.textContent = e; out.className = 'error'; } } updateResult(); form.addEventListener('input', updateResult); 
 body { font-family: Arial, sans-serif; display: flex; flex-wrap: wrap; } input[type="text"] { margin-left: 6px; max-width: 30px; } label + label { margin-left: 10px; } output { font-family: monospace; } .error { color: #c00; } div { margin-right: 30px; } 
 <!-- FormData polyfill for older browsers --> <script src="https://unpkg.com/formdata-polyfill@3.0.17/formdata.min.js"></script> <div> <h3>Form</h3> <form id="form"> <label>x:<input type="text" name="x" value="1"></label> <label>y:<input type="text" name="y" value="2"></label> <label> z: <select name="z"> <option value="a" selected>a</option> <option value="b" selected>b</option> </select> </label> </form> </div> <div> <h3>Query string</h3> <output for="form"></output> </div> 

与IE 10兼容

对于更老的浏览器(例如IE 10),使用FORMDATA填充工具 ,一个Array.from填充工具如果必要的话,该代码:

Array.from(
  new FormData(formElement),
  e => e.map(encodeURIComponent).join('=')
).join('&')


Answer 4:

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



Answer 5:

下面是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()方法的结果。



Answer 6:

我开始与Johndave Decano答案。

这应该可以解决一些在答复他的功能提到的问题。

  1. 用+符号替换%20。
  2. 提交/如果他们点击提交表单按钮类型才会被提交。
  3. 复位按钮将被忽略。
  4. 该代码似乎是多余到我,因为它本质上是做同样的事情,无论字段类型。 且不说与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))">


Answer 7:

如果您需要提交表单“myForm的” JSON格式使用POST,你可以这样做:

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被施加到每个[“一个”,“B”]一对,并将它们转换成{“一个”:“B”},以使阵列中含有大量的对象的仅具有一个在每个属性。 该mapFn用“解构”,以获得对的第一和第二部分的名称,它也使用ES6“ComputedPropertyName”由mapFn返回的对象设置属性名称(这就是为什么说“[ X]:东西”,而不仅仅是 “X:东西”。

所有这些单一属性的对象然后被传递到其中合并所有单个属性的对象到具有所有特性的单一对象的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/

更多关于计算的属性名称的位置: 变量作为一个JavaScript属性名对象常量?



Answer 8:

工程在所有浏览器。

 function formSerialize(formElement) { const values = {}; const inputs = formElement.elements; for (let i = 0; i < inputs.length; i++) { values[inputs[i].name] = inputs[i].value; } return values; } const r = formSerialize(document.querySelector('form')); console.log(r); console.log(JSON.stringify(r)); 
 <form action="/my-handling-form-page" method="post"> <div> <label for="name">Name:</label> <input type="text" id="name" name="user_name" value="John"> </div> <div> <label for="mail">E-mail:</label> <input type="email" id="mail" name="user_mail" value="john@jonhson.j"> </div> <div> <label for="msg">Message:</label> <textarea id="msg" name="user_message">Hello My Friend</textarea> </div> </form> 



Answer 9:

如果您正在寻找序列化对事件的输入。 这里有一个纯JavaScript的方法,我用。

// serialize form
var data = {};
var inputs = [].slice.call(e.target.getElementsByTagName('input'));
inputs.forEach(input => {
  data[input.name] = input.value;
});

数据将是输入的JavaScript对象。



Answer 10:

使用较少的变量和采取的速度优势@ SimonSteinberger的代码重构一个版本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, '+');
}


Answer 11:

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();

我希望我已经帮助。



Answer 12:

我重构TibTibs回答到的东西,是更清晰阅读。 这是因为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);
}


Answer 13:

  // 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);


Answer 14:

我从@moison答案抢过项()FORMDATA的方法和MDN它说:

所述FormData.entries()方法返回一个迭代允许经过包含在该对象中的所有键/值对。 每对中的密钥是一个USVString对象; 的值或者是USVString或斑点。

但唯一的问题是,手机浏览器(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'

};

该代码可以发现这里



Answer 15:

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;
}


Answer 16:

为了进行调试,这可能帮助你:

function print_form_data(form) {
    const form_data = new FormData(form);

    for (const item of form_data.entries()) {
        console.log(item);
    }

    return false;
}


Answer 17:

我可能是疯了,但我发现这些答案认真臃肿。 这里是我的解决办法

function serialiseForm(form) {
  var input = form.getElementsByTagName("input");
  var formData = {};
  for (var i = 0; i < input.length; i++) {
    formData[input[i].name] = input[i].value;
  }
  return formData = JSON.stringify(formData);
}


Answer 18:

使用JavaScript功能降低应为所有的浏览器做了一招,包括IE9>:

Array.prototype.slice.call(form.elements) // convert form elements to array
    .reduce(function(acc,cur){   // reduce 
        var o = {type : cur.type, name : cur.name, value : cur.value}; // get needed keys
        if(['checkbox','radio'].indexOf(cur.type) !==-1){o.checked = cur.checked;} // if input is checkbox or radio type
        acc.push(o);
        return acc;
 },[]);

活生生的例子波纹管。

 var _formId = document.getElementById('formId'), formData = Array.prototype.slice.call(_formId.elements).reduce(function(acc,cur,indx,arr){ var o = {type : cur.type, name : cur.name, value : cur.value}; if(['checkbox','radio'].indexOf(cur.type) !==-1){o.checked = cur.checked;} acc.push(o); return acc; },[]); // view document.getElementById('formOutput').innerHTML = JSON.stringify(formData, null, 4) 
 <form id="formId"> <input type="text" name="texttype" value="some text"> <select> <option value="Opt 1">Opt 1</option> <option value="Opt 2" selected>Opt 2</option> <option value="Opt 3">Opt 3</option> </select> <input type="checkbox" name="checkboxtype" value="Checkbox 1" checked> Checkbox 1 <input type="checkbox" name="checkboxtype" value="Checkbox 2"> Checkbox 2 <input type="radio" name="radiotype" value="Radio Btn 1"> Radio Btn 1 <input type="radio" name="radiotype" value="Radio Btn 2" checked> Radio Btn 2 </form> <pre><code id="formOutput"></code></pre> 



文章来源: form serialize javascript (no framework)