10 回答
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))
}
我建议对获取数据并填充下拉列表的代码进行分析。其他事情可能会占用时间。例如,检查“分解”从服务器返回的字符串值的代码是否清晰(听起来您正在那里进行自己的自定义解析)。
第一个代码很好,但这对我来说效果更好:
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))
}
SelectElement.innerHTML 的所有这些答案的问题在于,您不能使用 SELECT 来完成这个技巧。解决方案是在 SELECT 元素本身的 PARENT 上使用 innerHTML。因此,在您的 ajax/jquery/whatever 代码中创建一个包含所有 SELECT HTML 的字符串,然后获取持有者(div 或 span 或其他)并将 innerHTML 设置为您构建的字符串。
您需要将 SELECT 与页面隔离,并为其指定一个显式父元素(span 或 div),以防止其他 html 元素在您销毁/重建 SELECT 元素时造成伤亡。
简短的回答:
parentselectelement.removeChild(selectelement);
parentselectelement.innerHTML = "<select ...><options...></select>";
使用SelectElement.innerHTML设置它是最快的......但是在 IE 中失败了。
最后我检查了一下,你可以在 IE 中执行此操作,如果你将所有选项包装在一个虚假的<div>标记中,或者在 IE 中设置选择列表的整个 .outerHTML。
我会在服务器上创建整个选择并将其注入页面。这种方法绕过了恼人的浏览器差异,并降低了客户端代码的复杂性。
You did mention that you tried that, but it failed in firefox. I would suggest persevering in getting it to work, posting another question asking for help on that issue, or editing your question to show us what you made that didn't work in firefox.
document.createDocumentFragment()
在将其附加到 SELECT 之前,不要忘记先附加到。
如果您不介意使用 CoffeeScript,那么下面的代码用几行 JSON 数据填充选择列表。
HTML
<select id="clients"></select>
咖啡脚本
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
生成整个 html 字符串。这是很好和有效的。append
示例 JSON
[
{"Id":"1","Name":"Client-1"},
{"Id":"2","Name":"Client-2"}
]
查看您的代码将有很大帮助。
如果您正在创建一个<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)
当我使用它的第一个版本时,它可以工作,但更新第二个选择时可能会很慢
<html> <form id='myform' method='post' action='$_SERVER[PHP_SELF]'> <表格> <tr><td><select onselect='CALL_AJAX_AND_UPDATE();'></select></td></tr> <tr><td><select id='selectid'></select></td></tr> </table> </form> </html> <脚本类型=\"文本/javascript\"> 函数更新(更新数据) { var itemid = document.getElementById('selectid'); var data = updatedata.split('|'); var len = 数据长度; 对于(我=0;我<长度;我++) { var opt = document.createElement('option'); opt.text = 数据[i]; 尝试 { itemid.add(opt, null); } 抓住(前) { itemid.add( 选择 ); } } } </脚本>
这个版本在 IE 中工作,但 firefox 似乎没有发布第二个选择数据。我错过了什么吗?
<html> <form id='myform' method='post' action='$_SERVER[PHP_SELF]'> <表格> <tr><td><select onselect='CALL_AJAX_AND_UPDATE();'></select></td></tr> <tr><td><div id='addselect'></div></td></tr> </table> </form> </html> <脚本类型=\"文本/javascript\"> 函数更新(更新数据) { // 更新数据是full select html var itemid = document.getElementById('addselect'); itemid.innerHTML = 更新数据; } </脚本>
我喜欢 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]));
}