这个功能可以更快吗?使用Javascript

时间:2009-09-11 20:47:21

标签: 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 another array by manually looping through tagArray and adding 
it to resultingArray (the return type is dynamic collection and not an array.

从功能上讲,它可以工作,但需要很长时间。有没有办法做我想做的更快?

6 个答案:

答案 0 :(得分:4)

基于Ben的elements idea,这是另一个非嵌套循环的镜头。

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浏览器中),而elements仅返回表单控件。

答案 1 :(得分:2)

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

var $elements = jQuery( '#id-of-table input, #id-of-table textarea' );
$elements.each( function( i, element )
{
   // whatever you need here
} );

答案 2 :(得分:1)

如果您的输入和textareas都在同一个<form>内,请查看form.elements 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);
    }
}

您也可以查看XPath表达式,但要注意浏览器差异(例如,下面的代码在IE中不起作用,尽管有替代方法)。

var result = document.evaluate(tags.join("|"), table, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);

答案 3 :(得分:1)

您可以调用或应用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']);

请记住,这不会按文档顺序返回节点。它会将所有<input>组合在一起并将所有<textarea>组合在一起。

答案 4 :(得分:0)

我不是100%确定我理解你要做的事情,但这可能会指出你正确的方向(注意它使用jQuery):

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
    function getStuff(){
        resultArr = [];
        var inputs = $('#myTbl').find('input');
        var tareas = $('#myTbl').find('textarea'); 
        // do the looping bit which I don't completely understand
    }
</script>

答案 5 :(得分:-1)

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

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

然后我就开始使用jQuery选择器了!