【问题标题】:filtering ul li with jquery用jquery过滤ul li
【发布时间】:2015-03-18 07:35:54
【问题描述】:

我有 1 ul,里面有 10000 li 我需要使用包含符号来过滤它们。

我正在使用 Jquery 2.1.3 并写了这个函数

$("#filter").keyup(function(){
        var filter = $(this).val(), count = 0;
        if(!filter){
            $(".wordlist li").slideUp('slow', function(){
                $('.wordlist').css({'border': 'none', 'background': 'transparent'});
            });
            return;
        }
        var regex = new RegExp(filter, "i");
        $('.wordlist li').each(function(){
            if ($(this).find('.trans').text().search(regex) < 0) {
                $(this).slideUp('slow');
            } else {
                $(this).slideDown('slow');
                count++;
            }
        });
    });

这段代码工作正常,但是 用jquery .each()搜索需要很长时间

我需要函数在最短的时间内完成这项工作。

谁能帮帮我?

这是我正在做的提琴手 https://jsfiddle.net/giasoft/4o84t1fp/

【问题讨论】:

标签: jquery regex filter


【解决方案1】:

我想到了以下几点:

console.log("1:" + new Date().getTime());
var words = $('.wordlist li');// search take time, check this 20 li in 8ms
console.log("2:" + new Date().getTime());
var filter = $("#filter");
var timer = null;
$("#filter").keyup(function(){
    if (timer != null) {
        clearTimeout(timer);
        timer = null;
    }
    timer = setTimeout(function() {
        var filterStr = filter.val(), count = 0;
        console.log(filterStr);
        if(!filterStr){
           words.each(function(){
               $(this).slideDown('slow');
           });
           return;
        }
        var regex = new RegExp(filter, "i");
        /*below take time too*/
        console.log("3:" + new Date().getTime());
        words.each(function(){
            var ret = $(this).children('.trans').text().search(regex); 
            // children faster than find! or we should store text in array like "words" - words = [{this:this, text: text}], cache those text()
            // some problem here with search, 'A B C' match with 'aaaa'!
            //console.log($(this).children('.trans').text());
            console.log(ret);// 
            if (ret < 0) { 
                $(this).slideUp('slow');
            } else {
                $(this).slideDown('slow');
                count++;
            }
        });
        console.log("4:" + new Date().getTime());
        timer = null;
    }, 500);// do not need search each keyup!

});

但最大的问题是你的 10000 里!在 jsfiddle 中,过滤 20 li 需要 20 毫秒!您可以在脚本中手动为您的 li 建立索引(一个大数组而不是 each()、children() 或 finde(),但也很耗时)。

你会在你的服务器中建立一个索引(java-lucence 或任何其他东西)吗?您可以通过 $.ajax 使用关键字(用于搜索)从服务器获取数据(json/xml 格式)。而且,您可以将数据拆分为页面!每个 $.ajax 都可以用“开始”和结束来限制。服务器端解决方案似乎不仅仅是脚本

幻灯片解决方案的伪代码 HTML:

<div id=“searchResult” class="main container" style="overflow-y: auto;overflow-x: hidden;">
<ul class="list-group wordlist">
 ….
</ul>
</div>

脚本:

 //after keyword changed 
 //query from server, post as a example
 $.post("url", {key:"xxx", skip: skipNum, limit: limitNum}, function(response){
    data = $.toJSON(response); // if your returning data in JSON

    // fade old ul
    $("#searchResult").chidren(".wordlist")
    .animation({"marginLeft": "-xxxpx"}, "fast", "linear", function() {

        //remove old result
        //assume $(this) as $("#searchResult").chidren(".wordlist")
        $(this).remove();
    });

    // assume here after removing old result if above was sync
    // add new ul foreach result in return data
    var newUl = $("<ul>").css({"display", "none", "marging-left": "yyypx"});// hide at first;
    for (var i in data) {
        $("<li>")
         ..... // style , text ,chidren node in li
       .appendTo(newUl);// append to ul
    }
    newUl.appendTo($("#searchResult"));

    //slide the new ul
    newUl.css("display", "block"); //make it display 
    newUl.animation({"marginLeft":"0px"}.....);
}

另外,你可以用css3做动画

【讨论】:

  • 我需要上滑和下滑动画,因为我正在尝试这样做。但我也可以非常快速地在 mysql 中搜索此信息。但我需要页面上的动画。
  • 使用服务器端解决方案而不是滑动和向上滑动的向左移动动画怎么样 1 旧的搜索结果在向左移动时消失 2 新结果在从右侧移动时出现,或者像一页重叠其他,不使用 $.each
  • 我的意思是用
      而不是
    • 制作动画
  • danzeer:你能举个例子吗?
  • 据我了解,您建议我在 mysql 中过滤这些字符串,然后在 json 数组中使用 php 转换并进入 js?所以在那之后我不再需要用js过滤了。对吗?
【解决方案2】:

首先,当您为每个元素执行以下代码时:

if ($(this).find('.trans').text().search(regex) < 0)...

这会执行 10000 个选择器查询。

为避免这种情况,您可以在页面加载时将数据分配给元素,而不是每次都搜索内容

$('.wordlist li').each(function() {
  this.word=$(this).find('.trans').text();
});

然后将这个选择器替换为:

if (this.word.search(regex) < 0) {

请发现它在这里工作: https://jsfiddle.net/mcao0xhy/1/

您也可以将其分配给.data() 而不是对象属性——这样会更好。

$('.wordlist li').each(function() {
  $(this).data('word')=$(this).find('.trans').text();
});

然后:

if (this.data('word').search(regex) < 0) {

您也可以创建自己的选择器或使用现有的选择器,而不是使用每个选择器:http://james.padolsey.com/javascript/regex-selector-for-jquery/ 但这可能需要对 html 进行一些更改

【讨论】:

  • 没有。它没有按我的需要工作。而搜索谷歌浏览器的功能让我等待弹出窗口。 google chrome、opera 和 mozila 在搜索时崩溃。
  • 4:1426709735252 这是 10000 里 dfens 函数的 console.log 结果。过滤的时候可以一张一张往下滑吗?它会减少时间。对于用户
猜你喜欢
相关资源
最近更新 更多
热门标签