这个功能可以更快吗?Javascript

这个功能可以更快吗?Javascript,javascript,optimization,Javascript,Optimization,我有一个函数,它在一个div中获取一个DOM元素数组(基于标记) Pseudocode: 1. Say I wanted to get all input and textarea elements within a table myTbl 2. Declare resultingArray = null 3. For each tag (ex: input, textarea) 4. tagArray = Get all elements based on tag 5. Create

我有一个函数,它在一个div中获取一个DOM元素数组(基于标记)

Pseudocode:
1. Say I wanted to get all input and textarea elements within a table myTbl
2. Declare resultingArray = null
3. For each tag (ex: input, textarea)
4.   tagArray = Get all elements based on tag
5.   Create another array by manually looping through tagArray and adding 
it to resultingArray (the return type is dynamic collection and not an array.

从功能上讲,它可以工作,但时间太长。有没有办法更快地完成我想做的事情

我有类似的情况,表中有5列,最多1200行(并非所有行都填充了所有列)

所以我所做的只是将onclick处理程序放在一个表单元格的onmouseover事件上(将onclick hanlders立即放在td上也会花费太长时间)。onclick处理程序将使用在表单元格中找到的文本创建textarea


然后我就用jQuery选择器逃脱了

如果输入和文本区域都在同一个
中,请查看DOM属性。这样,您的代码可以简化为:

var resultingArray = document.getElementById("form-name").elements;
编辑:

如果您的标记名列表是动态的,并且您不能使用库,我认为您将无法轻松摆脱循环方法,但您可以尝试使其尽可能轻:

var result = [], nTags = tags.length, elements, nElements;

for (var i = 0; i < nTags; i++) {
    elements = table.getElementsByTagName(tag);
    nElements = elements.length;

    for (var j = 0; j < nElements; j++) {
        result.push(element);
    }
}

我不能百分之百确定我是否理解您的意图,但这可能会为您指明正确的方向(请注意,它使用jQuery):


函数getStuff(){
结果r=[];
变量输入=$('myTbl')。查找('input');
var tareas=$(“#myTbl”).find('textarea');
//做我不完全理解的循环部分
}

这绝对是需要jQuery解决方案的问题类型

var $elements = jQuery( '#id-of-table input, #id-of-table textarea' );
$elements.each( function( i, element )
{
   // whatever you need here
} );
根据Ben的,这是另一张非嵌套循环的照片

var tagNames = { 'SELECT' : true, 'INPUT' : true, 'TEXTAREA' : true }; //use an object for faster lookups
var rawElemsArray = document.getElementById("form-name").elements;
var elems = [];
for (var i = rawElemsArray.length - 1; i >= 0; i--) {
    if (tagNames[rawElemsArray[i].tagName]) {
        elems.push(rawElemsArray[i]);
    }
}

编辑:
form.elements
是在0级DOM中定义的,所以我打赌它是跨浏览器的。如果满足您的需要,您还可以使用
childNodes
(这也是跨浏览器的)。它们之间的区别在于,
childNodes
选择所有节点(div、p、span等)以及空文本节点(在非IE浏览器中),而
元素
仅返回表单控件。

您可以调用或将Array.slice应用于HTMLCollection以将其转换为字符串。这允许您使用concat,我认为这是最快的解决方案:

function getElementsByTagNames(context, tags) {
    var res = [], 
        i = tags.length,
        slice = Array.prototype.slice;

    // Convert HTMLCollections to arrays and push onto the res array
    while(i--) res.push(slice.call(context.getElementsByTagName(tags[i])));

    // Use one concat call to merge all the arrays
    return Array.prototype.concat.apply([], res);
}

getElementsByTagNames(document.body, ['input', 'textarea']);

请记住,这不会按文档顺序返回节点。它将返回所有分组在一起的
,以及所有分组在一起的

问题是,如果不手动循环元素,我无法组合两个数组。也许这会有所帮助:我不能使用JQuery。我正在寻找一个Javascript解决方案我不想得到所有的元素。我只选择了少数(输入、跨度等-此列表是动态构建的)尝试了您的解决方案。它在功能上起作用。但是它实际上比我以前的解决方案多了30%:(天哪,我无法想象为什么;这应该是最简单的!;-)
for…在
中,在JS中循环数组或节点列表不是正确的构造,你需要
来(i=0;i@bobince-没错!很明显,我将
for…in
foreach…in
混为一谈,这甚至不是跨浏览器。我已经更正了我的示例。非常优雅。这应该比循环
getElementsByTagName
要快得多。这很好,但它只适用于表单元素,特别是form元素都是相同的形式。我知道Ben的帖子中已经提到了这一点,但这一点似乎足够重要,需要再次提及。此解决方案是否跨浏览器兼容?如果您首先对集合进行切片,则可以使用concat。这是将动态节点列表转换为数组的一种非常快速的方法。我在下面发布了一些代码,其中有g此处的ood信息:
var tagNames = { 'SELECT' : true, 'INPUT' : true, 'TEXTAREA' : true }; //use an object for faster lookups
var rawElemsArray = document.getElementById("form-name").elements;
var elems = [];
for (var i = rawElemsArray.length - 1; i >= 0; i--) {
    if (tagNames[rawElemsArray[i].tagName]) {
        elems.push(rawElemsArray[i]);
    }
}
function getElementsByTagNames(context, tags) {
    var res = [], 
        i = tags.length,
        slice = Array.prototype.slice;

    // Convert HTMLCollections to arrays and push onto the res array
    while(i--) res.push(slice.call(context.getElementsByTagName(tags[i])));

    // Use one concat call to merge all the arrays
    return Array.prototype.concat.apply([], res);
}

getElementsByTagNames(document.body, ['input', 'textarea']);