在JavaScript中合并两个对象(节点列表)数组
我正在尝试将两个对象数组合并到,以便验证表单。通常的concat方法在这种情况下似乎不起作用。Concat适用于普通的数值数组和字符串数组,但不适用于对象数组。行在JavaScript中合并两个对象(节点列表)数组,javascript,arrays,object,merge,Javascript,Arrays,Object,Merge,我正在尝试将两个对象数组合并到,以便验证表单。通常的concat方法在这种情况下似乎不起作用。Concat适用于普通的数值数组和字符串数组,但不适用于对象数组。行var allTags=allInputs.concat(allSelects)不起作用 var allInputs = document.getElementsByTagName("input"); alert("Inputs: " + allInputs.length); var allSelects = document.get
var allTags=allInputs.concat(allSelects)代码>不起作用
var allInputs = document.getElementsByTagName("input");
alert("Inputs: " + allInputs.length);
var allSelects = document.getElementsByTagName("select");
alert("Selects: " + allSelects.length);
var allTags = allInputs.concat(allSelects);
alert("allTags: " + allTags.length);
Concat适用于普通的数值数组和字符串数组,但不适用于对象数组
实际上,它是这样的,但是NodeList
实例没有concat
方法,而且Array#concat
没有一种方法来确定您想要展平这些实例(因为它们不是数组)
但这仍然相当容易做到(不过请参见下面的警告)。更改此行:
var allTags = allInputs.concat(allSelects);
到
|
这是通过使用一些技巧实现的:接受可变数量的元素添加到数组中,并使用this
(在我们的例子中,allTags
)的给定值和任何类似数组的对象作为传递给它的参数来调用函数。由于NodeList
实例类似于数组,push
愉快地将列表中的所有元素推送到数组中
Function#apply
(不要求第二个参数真正是数组)的这种行为在规范中定义得非常清楚,在现代浏览器中得到了很好的支持
遗憾的是,IE6和IE7不支持上述内容(我认为它专门使用主机对象--节点列表---for函数#apply
的第二个参数),但是,我们也不应该支持它们。:-)IE8也没有,这更成问题。IE9对此很满意
如果您需要支持IE8及更早版本,很遗憾,我认为您陷入了一个无聊的老循环:
var allInputs = document.getElementsByTagName('input');
var allSelects = document.getElementsByTagName('select');
var allTags = [];
appendAll(allTags, allInputs);
appendAll(allTags, allSelects);
function appendAll(dest, src) {
var n;
for (n = 0; n < src.length; ++n) {
dest.push(src[n]);
}
return dest;
}
var allInputs=document.getElementsByTagName('input');
var allSelects=document.getElementsByTagName('select');
var-allTags=[];
appendAll(所有标签、所有输入);
appendAll(所有标签,所有选择);
函数appendAll(dest,src){
var n;
对于(n=0;n
|
这对IE8和早期版本(以及其他版本)有效。是否研究过underline.js?你可以
var allSelectsAndInputs = _.union(_.values(document.getElementsByTagName("input")),_.values(document.getElementsByTagName("select")));
有关更多信息,请参阅:
该函数用于对象,但在此设置下工作。document.get[something]
返回a,它看起来非常类似于,但具有许多不同的功能,其中两个是:
- 它不包含concat方法
- 项目列表是实时的。这意味着它们会随着文档的实时更改而更改
如果在将节点列表转换为实际阵列方面没有任何问题,可以执行以下操作以实现所需的效果:
var allInputs = document.getElementsByTagName("input")
, allSelects = document.getElementsByTagName("select")
;//nodeLists
var inputList = makeArray(allInputs)
, selectList = makeArray(allSelects)
;//nodeArrays
var combined = inputList.concat(selectList);
function makeArray(list){
return Array.prototype.slice.call(list);
}
您将失去原始节点列表的任何和所有行为,包括它实时更新以反映DOM更改的能力,但我的猜测是,这不是一个真正的问题。您正在处理的是HTMLCollection
s,它们是实时集合(即,当您将节点添加到DOM中时,它将自动添加到集合中
不幸的是,它没有一个concat
方法…这是有原因的。您需要做的是将它转换为一个数组,失去它的活动行为:
var allInputsArray = [].slice.call(allInputs),
allSelectsArray = [].slice.call(allSelects),
allFields = allInputsArray.concat(allSelectsArray);
我找到了一种简单的方法,可以按照dom对象在页面或表单上的显示顺序收集它们。
首先,在对象上创建一个伪类样式“reqd”,然后使用下面的命令,按照它们在页面上出现的顺序创建一个列表。只需将该类添加到您希望收集的任何对象中即可
var allTags = document.querySelectorAll("input.reqd, select.reqd");
这不是数组,而是类似于数组的对象(NodeList)事实上,它是一个NODLIST,因此不具有CONTAT方法。实际上,我正在玩它。它看起来有点关闭。站起来。如果你喜欢它,考虑投票我的答案。@ USER 2035797:不用担心,我现在还添加了一个在IE8和更早的作品上的例子。预先警告,就像我在ANSW的第一部分中给出的类似的解决方案一样。呃,这在IE8或更早版本中是行不通的。(在这里试试:)唉,至少IE9是不错的。所以对于IE8或更早版本,你需要一个无聊的老循环。
var allTags = document.querySelectorAll("input.reqd, select.reqd");