使用Javascript </select>填充<select>的更快方法

时间:2009-03-30 20:04:47

标签: javascript ajax internet-explorer performance html-select

我有两个&lt; select&gt;表格上的方框。选择第一个&lt; select&gt;中的项目框将确定第二个&lt; select&gt;中应显示的内容(使用Ajax http_request)。

在某些情况下,第二个选项中可能有500个(猜测)项目,在IE中更新需要5-10秒。 Firefox似乎完美无缺。

我想知道是否有更快的方法来实现这一目标。当前服务器创建一个字符串将其传递给客户端,然后将其分解并通过创建选项元素将每个项目添加到选择中,然后将其添加到&lt; select&gt;。

我确实尝试在服务器上创建整个选择项作为字符串并将其添加到表单但由于某种原因它在Firefox中不起作用(错过了什么?)

由于

10 个答案:

答案 0 :(得分:19)

500个元素并不是很多,即使对于IE来说也是如此。你必须做其他事情才能造成滞后。

我刚尝试了IE6,IE7,FF2和FF3中的500多个选项,并且都接近瞬间。我用了这段代码:

var data = [
    { text: 'foo', value: 'bar' },
    // ...
    { text: 'foo', value: 'bar' }
];

var select = document.getElementsByTagName('select')[0];
select.options.length = 0; // clear out existing items
for(var i=0; i < data.length; i++) {
    var d = data[i];
    select.options.add(new Option(d.text, i))
}

我建议分析一下获取数据并填充下拉列表的代码。还有其他东西可能占用时间。例如,检查“分解”从服务器返回的字符串值的代码是否清晰(听起来就像你在那里进行自己的自定义解析)。

答案 1 :(得分:4)

第一个代码很好,但这对我来说效果更好:

var data = [
    { text: 'uno', value: '1' },
    {text: 'dos', value: '2' }
];

var select = document.getElementById('select-choice-1');
select.options.length = 0; // clear out existing items
for (var i = 0; i < data.length; i++) {
    var d = data[i];
    select.options.add(new Option(d.text, d.value))
}

答案 2 :(得分:2)

使用 SelectElement.innerHTML 设置它将是最快的......但 that FAILS in IE

最后我检查过,你可以在IE中执行此操作,如果你将所有选项包装在伪&lt; div&gt; 标记中,或者在IE中设置选择列表的整个.outerHTML。 / p>

答案 3 :(得分:2)

使用SelectElement.innerHTML解决所有这些问题的问题在于,您无法使用SELECT执行此操作。解决方案是在SELECT元素本身的PARENT上使用innerHTML。所以在你的ajax / jquery /无论代码中创建一个包含所有SELECT HTML的字符串,然后获取持有者(div或span或其他)并将innerHTML设置为你构造的字符串。

您需要将SELECT与页面隔离,并为其提供一个显式父元素(span或div),以防止在销毁/重构SELECT元素时其他html元素成为伤亡。

简短回答:

parentselectelement.removeChild(selectelement);
parentselectelement.innerHTML = "<select ...><options...></select>";

答案 4 :(得分:1)

我会在服务器上创建整个选择并将其注入页面。这种方法绕过了恼人的浏览器差异,并降低了客户端代码的复杂性。

你确实提到过你试过了,但它在firefox中失败了。我建议坚持让它发挥作用,发布另一个问题,在这个问题上寻求帮助,或者编辑你的问题,向我们展示你在firefox中无效的内容。

答案 5 :(得分:1)

在将其附加到SELECT之前,不要忘记先附加到document.createDocumentFragment()

答案 6 :(得分:0)

查看代码会有很大帮助。

如果您要在每次迭代时创建<option>元素,则应考虑一次创建所有<option>元素,然后一次性附加所有元素。

所以(在伪代码中):

// Don't do this:
for choice in choices:
    option = new Options(choice)
    select.append(option)


// Do this instead
var options = array()

for choice in choices:
   options.append( new Options(choice) )

for option in options:
   select.append(option)

// Or you might try building the select element off-screen and then appending to the DOM
var options = array()
var select = new SelectElement()

for choice in choices:
   select.append( new Options(choice) )

dom_element.append(select)

答案 7 :(得分:0)

当我使用它的第一个版本时,它可以工作,但在更新第二个选择

时可能会很慢
<html>
<form id='myform' method='post' action='$_SERVER[PHP_SELF]'>
<table>
<tr><td><select onselect='CALL_AJAX_AND_UPDATE();'></select></td></tr>
<tr><td><select id='selectid'></select></td></tr>
</table>
</form>
</html>

<script type=\"text/javascript\">
function UPDATE( updatedata )
{                   
    var itemid = document.getElementById('selectid');               

    var data = updatedata.split( '|' );
    var len = data.length;                                                          

    for( i=0; i < len; i ++ )
    {
        var opt = document.createElement('option');
        opt.text = data[i];

        try
        {
            itemid.add( opt, null );                        
        }
        catch(ex)
        {
            itemid.add( opt );      
        }       
    }                                           
}
</script>

此版本适用于IE,但firefox似乎没有发布第二个选择数据。我错过了什么。

<html>
<form id='myform' method='post' action='$_SERVER[PHP_SELF]'>
<table>
<tr><td><select onselect='CALL_AJAX_AND_UPDATE();'></select></td></tr>
<tr><td><div id='addselect'></div></td></tr>
</table>
</form>
</html>

<script type=\"text/javascript\">
function UPDATE( updatedata )
{               
    // update data is full select html  
    var itemid = document.getElementById('addselect');              
    itemid.innerHTML = updatedata;                                                          
}
</script>

答案 8 :(得分:0)

我喜欢Crescent Fresh和Kemal Fadillah的回答,因为两者都使用:

select.options.add(new Options(name, value))

对于数据对象,我建议进行如下小调整:

var data = {
  'uno': 1,
  'dos': 2
};

var select = document.getElementById('select-choice-1');
select.options.length = 0; // clear out existing items
for (var i in data) {
      select.options.add(new Option(i, data[i]));
}

答案 9 :(得分:0)

如果你不介意使用CoffeeScript,那么下面的代码用几行中的JSON数据填充选择列表。

<强> HTML

<select id="clients"></select>

<强>的CoffeeScript

fillList=($list, url)=>
    $.getJSON(url)
    .success((data)->
        $list
        .empty()
        .append("<option value=\"#{item.Id}\">#{item.Name}</option>" for item in data)
    )

$ -> 
    fillList($('#clients'), '/clients/all')

注意append内的循环在调用append方法一次之前生成整个html字符串。这很好而且效率很高。

示例JSON

[
  {"Id":"1","Name":"Client-1"},
  {"Id":"2","Name":"Client-2"}
]