表单事件处理模式
Form Event Handling Pattern
我使用的是后端,理想的情况是发送ajax post请求,而不是在表单上使用默认操作。
考虑到这一点,我需要提取在我的表单中选择的最终字段
我有各种文本字段、单选按钮、复选框等
我一直在努力获得对活动授权和活动传播的良好理解。我不完全确定这是否是我努力实现的目标应该担心的话题。
我知道我可以编写代码,通过在每个字段上放置一个ID来获取表单中的所有信息,并使用一个函数提取ID上的每个值,例如:
function example(){
var field0 = $('#field0').val();
var field1 = $('#field1').parent().hasClass('active')
// ... and more
}
我用这种模式已经有一段时间了,我觉得它没有效率。
我有两种模式的想法,但我仍然不确定这是否是的"常见做法"
由于在提交表单之前,我不关心每个字段中的数据,因此我可以对表单上所有基于输入的字段运行循环并提取内容,而不是为每个单独的输入字段分配ID。
我可以听取表单上的更改(我不确定如何做到这一点,这就是事件委派/传播将发挥作用的地方)。我将使用某种类型的侦听器来检测表单上的更改(不确定是否可能),而不是等待提交按钮来收集表单中的所有信息。
我已经使用我目前的模式好几个月了,我想提高自己。如果有人对我对新方法的想法有任何建议、链接或批评,我将不胜感激。
因此,您基本上提出了3种方法来在提交(或类似事件)时获得具有值的所有表单字段:
- 硬代码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})
});
});
- 循环所有并检索它们的值,例如
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)
});
});
- 注意表单内部的变化,积累它们
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.querySelectorAll
、Array.reduce
和window.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);
- keyup事件处理程序更改焦点不适用于快速键入
- 提示使用服务器端事件处理程序激活JavaScript
- 将事件处理程序绑定到任何可能的事件
- 正在将事件处理程序添加到不存在的类
- dropdown.js中的复杂事件处理
- 在循环中附加事件处理程序时出现浏览器性能问题
- 在同一个javascript事件处理程序中调用不同的函数
- 复选框,然后单击事件处理
- 有没有一种方法可以让内联事件处理程序在元素创建后立即执行
- 检查事件处理程序参数
- 实现延迟的jquery更改事件处理程序
- 如何使用Node.js在JavaScript模块文件之间使用事件处理程序
- 模式弹出窗口无法正常工作,它多次调用函数 - 单击事件处理程序运行多次
- 难以将事件处理程序附加到动态生成的模式窗口元素
- 用于关闭模式弹出窗口的事件处理程序
- 将事件处理程序附加到多个文本框(具有相似的模式id)
- 使用事件处理程序的模块模式
- 处理常见JQuery事件处理模式的另一种方法
- 表单事件处理模式
- 要处理的模式'这'在JavaScript事件处理程序中