我使用javascript (React,但我不认为这是专门针对React的)来处理表单提交。我的元素都不受控制,我想让它保持这种状态。我可能事先不知道表单元素是什么,有多少,等等。我只想抓取表单中的任何内容,并将其发送到需要它去的任何地方。
我在事件处理程序中做了一些日志记录,这样我就可以检查event.target.elements
了,这有点让人困惑。它看起来同时像是一个索引数组和一个对象,每个表单元素都有一个数值条目和一个命名条目。它有一个等于数字条目数量长度的length
属性(忽略命名条目),但是如果我尝试在它上面直接使用.forEach
,就会得到错误event.target.elements.forEach is not a function
。如果我使用Object.entries
遍历它,那么数字和命名条目都会被记录下来。但是如果我使用lodash
遍历它,我只能得到数值条目。
我只想知道到底发生了什么。如果event.target.elements
不是数组,为什么它有length
属性?如果它是一个数组,为什么我不能直接在它上面使用常规的forEach
呢?
出于测试/学习的目的,我的表单提交事件处理程序如下所示:
let handleSubmit = async( event ) => {
event.preventDefault();
console.log("event.target.elements",event.target.elements);
console.log("event.target.elements",typeof event.target.elements);
Object.entries(event.target.elements).forEach(([name, input]) => {
console.log("name",name);
console.log("input",input);
});
console.log("------");
_.forEach(event.target.elements, (el,key)=>{
console.log("key",key);
console.log("name",el.name);
console.log("value",el.value);
});
}; // handleSubmit
输出如下,请注意,Object.entries
循环执行四次,而lodash
循环执行两次
event.target.elements HTMLFormControlsCollection(2) [input, select, test2: input, test1: select]
0: input
1: select
length: 2
test1: select
test2: input
__proto__: HTMLFormControlsCollection
event.target.elements object
name 0
input <input type="hidden" name="test2" value="asdf">
name 1
input <select name="test1">…</select>
name test2
input <input type="hidden" name="test2" value="asdf">
name test1
input <select name="test1">…</select>
------
key 0
name test2
value asdf
key 1
name test1
value 3
发布于 2021-06-12 01:29:01
实际上,答案就在您的代码示例中:它是一个HTMLFormControlsCollection
(MDN entry here)。
在JS中,不仅有Object
、Array
、Map
和Set
(OK、WeakMap
和WeakSet
),还有其他类型(集合),比如HTMLCollection
的“家族”。
它们都有自己的特点&可以在不同的用例中使用,但它们也可以通过一些迭代技术用作Array
:
const inputForm = document.getElementById("input-form")
inputForm.addEventListener('submit', (e) => {
e.preventDefault()
const el = e.target.elements
console.log("el.toString():", el.toString())
console.log("instanceof HTMLFormControlsCollection:", el instanceof HTMLFormControlsCollection) // expected: true
console.log("instanceof Array:", el instanceof Array) // expected: false
// iteration #1
// using map() on collections
const mapped = Array.prototype.map.call(el, (ele) => ele)
console.log("mapped:", mapped)
// iteration #2
// logs the elements
for (let ele of el) {
console.log("for...of:", ele)
}
// iteration #3
// logs the keys of the HTMLFormControlsCollection
for (let ele in el) {
console.log("for...in:", ele)
}
// iteration #4
const spread = [...el]
console.log("spread:", spread)
});
<form id="input-form">
<input type="text" />
<input type="text" />
<button type="submit">SUBMIT</button>
</form>
https://stackoverflow.com/questions/67941002
复制相似问题