实时编辑滑动html菜单

Posted

技术标签:

【中文标题】实时编辑滑动html菜单【英文标题】:Real time edit sliding html menu 【发布时间】:2012-11-28 19:55:51 【问题描述】:

我正在使用滑动菜单(选择/对象 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));
         
    

【问题讨论】:

你有多少个元素?在那个 searchSelect 中使用了克隆的 DOM 元素。可能将项目存储在常规 JS 数组中会有所帮助。 我猜超过 10k 个元素。当我开始打字时,大约需要 20 秒才能结束任务。如何将我的元素存储到常规 JS 数组中?不幸的是,我在 JS 上并不是那么“聪明”... 嗯... 10k 个元素?那是很多。不要认为即使是 JS 数组实际上也会有所帮助... AJAX 可能会有所帮助,但是一旦您尝试显示大量项目 - 无论如何它都会很慢(因为 dom 更新缓慢)。 是的,这就是问题所在。这些性能仅在旧版本的 IE 中,在 Chrome 上确实更快。顺便感谢您的提示! 【参考方案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 = "&lt;select id=\"testSelect\" mulitple=\"multiple\" size=\"4\"&gt;";)。这是 IE 的 this 错误的解决方法。

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

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

【讨论】:

感谢您的功能性和详细的回答。我试过你的代码,但它至少需要和我一样的时间(大约 10 秒)。太糟糕了,我想我们应该“处理” IE8 性能...... 您可以尝试构建自己的“选择”。只是一个包含其他项目 div 列表的 div。项目 div 包含复选框(因此您可以提交所选项目)和文本实际上,您可以隐藏复选框并完全模仿选择行为(只需处理单击文本并设置复选框选中/未选中)。并修改代码以显示/隐藏带有 style.display 属性的元素。我认为这应该更快。【参考方案2】:

我猜您正在尝试执行自动完成之类的操作。你试过http://api.jqueryui.com/autocomplete吗?

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

【讨论】:

我不想自动完成。当我在文本框中书写时,我的列表将自动“调整大小”,仅包含我输入的文本的值。当我删除一些文本时,我的列表会自动调整为原始长度。

以上是关于实时编辑滑动html菜单的主要内容,如果未能解决你的问题,请参考以下文章

html导航菜单溢出,想搞个可以左右滑动的菜单,请各位大侠帮帮忙!

【求助】SlidingMenu 左右滑动菜单与viewpage冲突问题

横向滑动菜单HorizontalScrollView

CSS3超酷移动手机滑动隐藏側边栏菜单特效

html5手机端的点击弹出侧边滑动菜单代码

自定义UITableViewCell实现左滑动多菜单功能LeftSwipe