表单事件处理模式

Form Event Handling Pattern

本文关键字:模式 事件处理 表单      更新时间:2023-09-26

我使用的是后端,理想的情况是发送ajax post请求,而不是在表单上使用默认操作。

考虑到这一点,我需要提取在我的表单中选择的最终字段

我有各种文本字段、单选按钮、复选框等

我一直在努力获得对活动授权和活动传播的良好理解。我不完全确定这是否是我努力实现的目标应该担心的话题。

我知道我可以编写代码,通过在每个字段上放置一个ID来获取表单中的所有信息,并使用一个函数提取ID上的每个值,例如:

function example(){
  var field0 = $('#field0').val();
  var field1 = $('#field1').parent().hasClass('active')
  // ... and more    
}

我用这种模式已经有一段时间了,我觉得它没有效率。

我有两种模式的想法,但我仍然不确定这是否是的"常见做法"

  1. 由于在提交表单之前,我不关心每个字段中的数据,因此我可以对表单上所有基于输入的字段运行循环并提取内容,而不是为每个单独的输入字段分配ID。

  2. 我可以听取表单上的更改(我不确定如何做到这一点,这就是事件委派/传播将发挥作用的地方)。我将使用某种类型的侦听器来检测表单上的更改(不确定是否可能),而不是等待提交按钮来收集表单中的所有信息。

我已经使用我目前的模式好几个月了,我想提高自己。如果有人对我对新方法的想法有任何建议、链接或批评,我将不胜感激。

因此,您基本上提出了3种方法来在提交(或类似事件)时获得具有值的所有表单字段:

  1. 硬代码ID并检索其值,例如
var field_a = document.getElementById('a')
  , field_b = document.getElementById('b')
  , form = document.getElementById('my_form');
form.addEventListener('submit', function() {
  fetch('//your/api/endpoint', {
    method: 'POST',
    body: JSON.stringify({a: field_a.value, b: field_b.value})
  });
});
  1. 循环所有并检索它们的值,例如
var form = document.getElementById('my_form');
form.addEventListener('submit', function() {
  var values = [].reduce.call(
    form.querySelectorAll('input, textarea, select'),
    function(values, element) {
      values[element.name] = element.value;
      return values;
    },
    {}
  );
  fetch('//your/api/endpoint', {
    method: 'POST',
    body: JSON.stringify(values)
  });
});
  1. 注意表单内部的变化,积累它们
var form = document.getElementById('my_form')
  , state = {};
form.addEventListener('change', function(e) {
  state[e.srcElement.name] = e.value;
});
form.addEventListener('submit', function() {
  fetch('//your/api/endpoint', {
    method: 'POST',
    body: JSON.stringify(state)
  });
});

从性能角度来看,选项1。将是最快的,其次是2,然后是3(对于最后的2,我不能100%确定,querySelectorAll可能很昂贵,但监听大量的change事件可能也是如此——我想这取决于触发更改事件的频率)。

从开发的角度来看(建立表单需要多长时间),2和3不应该有那么大的区别,因为它们都是通用的(您可以使用我的代码示例作为开始)。

"真实"数据绑定(如Angular)或"纯状态"(如React)也可以归结为选项2/3(只是框架将为您执行繁重的任务)。

关于选项3(在整个表单上侦听change):https://stackoverflow.com/a/4616720/1168892很好地解释了JavaScript中的事件冒泡是如何发生的。要使用它,您必须确保表单中没有元素取消change事件(否则它不会冒泡到表单本身)。不取消事件是默认行为,因此您必须明确地将其弄错(这样您就可以在实现中关注它)。


我在示例中没有使用jQuery,因为现在所有这些都可以通过浏览器直接完成。我使用的是Element.querySelectorAllArray.reducewindow.fetch

模式#1使用serializeArray

$('#formId').on('submit', function(e){
  var allData;
  e.preventDefault();
  allData = $(this).serializeArray();
  // use the allData variable when sending the ajax request
});

模式#2使用委托形式的$container.on('event', 'selector', ..)change事件

$('#formId').on('change', 'input,textarea,select', function(){
 var element = $(this), // element that changed
     value = element.val(); // its new value
 // do what you want ..
});

在没有jquery的情况下,我曾经写过一个函数,它在对象中返回与其名称相关的所有输入值。我认为它比普通的id链接要好,因为你不必担心表单中的内容,只要你给输入一个name属性。

function getFormData(form) {
   var data = {};
   for (var i = 0; i < form.elements.length; i++) {
      var input = form.elements[i];
      if (input.value && input.type !== 'submit' && input.type !== 'button') {
         data[input.name] = input.value;
      }
   }
   return data;
}

你所需要做的就是像这样传递你的表格:

var form = document.querySelector('.monFormulaire');
// your form data
var data = getFormData(form);