1

我正在使用一个滑动菜单(选择/对象 html 之一),它是通过使用 jsp 页面从数据库中获取数据而动态生成的。

我还有一个输入文本字段,我可以在其中从滑动菜单中搜索内容。我想写一个包含在我的菜单中的词的词根,我的菜单必须“调整大小”显示我写过的所有带有词根的项目,只有那些项目。

我不能使用服务器端操作(比如通过 post 发送数据),但我需要解决这个客户端(因为我需要立即得到这个结果)。

我实际上已经使用 javascript 解决了这个问题,但是这个解决方案存在一些性能问题,因为我必须使用 IE 8。

有没有使用 JQuery 或 Ajax 的类似解决方案?

这是类似于我的代码的内容:

HTML:

<select multiple id="testSelect">
    <option>test</option>
    <option>temp</option>
    <option>cast</option>
    <option>dest</option>
    <option>inst</option>
</select>

<input type="text" value="" onkeyup="searhSelect(this)" />​

每次按键时都会调用searhSelect 函数(当用户实际释放键时),并将过滤#testSelect 对象。

JS:

var optionsList;
function searhSelect(el) {
    var select = document.getElementById('testSelect');
    if(!optionsList) {        
        optionsList = select.cloneNode(true);  //copy select to a variable for future use      
    }
    select.innerHTML = "";//remove all options.

    for(var i =0; i < optionsList.options.length; i++) {
        var opt = optionsList.options[i];
        if(opt.innerHTML.indexOf(el.value) != -1) {
            select.appendChild(opt.cloneNode(true));
        } 
    }
}
4

2 回答 2

1

试试这样的代码:

var optionsList = [];
function searhSelect(el) {
    var select = document.getElementById('testSelect');

    if(optionsList.length == 0) {        
        for(var i = 0; i < select.options.length; i++)
            optionsList[i] = {key:select.options[i].value,value:select.options[i].innerHTML}; //copy select to a variable for future use      
    }   
    //if(el.value.length > 2) {
        var tmp = "<select id=\"testSelect\" mulitple=\"multiple\" size=\"4\">";
        for(var i =0; i < optionsList.length; i++) {
            var opt = optionsList[i];
            if(opt.value.indexOf(el.value) != -1) {                 
                tmp += ' <option value="' + opt.key + '" >' + opt.value + '</option> ';                        
            }         
        }   
        document.getElementById('test').innerHTML = tmp + "</select>";
    //}

}

HTML:

<div id="test">
   <select multiple id="testSelect">
      <option>test</option>
      <option>temp</option>
      <option>cast</option>
      <option>dest</option>
      <option>inst</option>
      <!-- in my test same options you see above were copy/pasted many times. I had little more than 10k  options->
   </select>
</div>

我已经删除了所有的 clone/appendChild,使用包含值和文本字段的对象推送所有元素 int 数组,最重要的是,现在使用 innerHTML 创建选项。另外,请注意 select 现在被另一个 div 包裹。而不是使用 select 的 innerHTML 并简单地设置选项 HTML,而是创建了带有整个 select HTML 的字符串 ( var tmp = "<select id=\"testSelect\" mulitple=\"multiple\" size=\"4\">";)。这需要作为IE的此错误的解决方法。

在您当前的实现中,一旦找到每个选项,就会一一添加。这样 IE 将在每次添加新选项时呈现元素 ()。但是上面的代码只会强制渲染一次 - 当所有选项都被定义时。不幸的是,这只是部分帮助。它比来自问题的代码工作得更快,但仍然需要大约 10 秒(与旧代码的 20-30 秒相比)来呈现新的选择元素(document.getElementById('test').innerHTML = tmp + "</select>";- 此时它正在冻结浏览器 10 秒)

我不认为您可以在不进行一些全局更改的情况下使其更快(例如,使用复选框自定义多选以选择一个元素,以及使用 display:block/none 显示/隐藏元素)。可能的解决方案 - 仅当过滤元素数量相对较少时才更新元素。例如 - 当要搜索的值的长度超过 2 个字符时(见注释掉//if(el.value.length > 2) {)。但是要使用它,当前的实现需要额外的编码(至少,一旦用户从输入字段中删除一些字符,完整的列表应该再次显示)。

于 2012-12-11T12:37:24.383 回答
0

我猜你正在尝试做一些类似自动完成的事情。你试过http://api.jqueryui.com/autocomplete吗?

或者您只是想过滤掉 SELECT 选项?然后我想隐藏/禁用它们而不是克隆它们更容易。

于 2012-12-11T10:46:46.257 回答