使用jQuery键入时过滤列表

我计划使用简单的数据库查询创建我的Web应用程序的无序用户列表,但随后计划让人们通过在文本输入中键入他们正在寻找的人名来过滤此列表。

我希望使用jQuery将输入框中的字符串与列表项中的任何一个匹配,然后隐藏其他项,可能是通过动态地将新类应用于包含匹配字符串的类,并隐藏所有其他类不包含该类。

有谁知道这样做的好方法?

假设您的ul具有theListid ,以下是执行此操作的一种方法。

   

或者,对于基于Marek Tihkan发布的更简洁的版本,您可以使用以下内容替换each()循环。 不确定这是否会表现更好或更差。

 $('#theList > li:not(:contains(' + value + '))').hide(); $('#theList > li:contains(' + value + ')').show(); 

如果输入文本为空,Nikolas给出的解决方案与Marek的解决方案之间会出现错误。
下面的解决方案纠正了该问题并适用于由“a”标记包围的列表。

该function还用于过滤元素,其首字母大写(例如带有名称)。 因此排序过滤。 如果您输入’An’或’an’,那么您将从这些字母开始获取列表中的所有元素(例如,Anthony将匹配但Fanny no)。

 function filter (element,what) { var value = $(element).val(); value = value.toLowerCase().replace(/\b[az]/g, function(letter) { return letter.toUpperCase(); }); if (value == '') { $(what+' > a > li').show(); } else { $(what + ' > a > li:not(:contains(' + value + '))').hide(); $(what + ' > a > li:contains(' + value + ')').show(); } }; 

下面是一个与脚本一起使用的示例HTML代码:

   

我通过迭代所有这些并隐藏那些不匹配的女巫并显示匹配的那些来做到了。

 $('li').hide(); $('li:contains(' + needle + ')').show(); 

您可以使用由John Resig从php移植到jQuery的LiveQuery 。

注意 :它依赖于PHP方法中的Quicksilver的score方法 ,该方法已被LiquidMetal.score和joshaven的string.score移植到JavaScript。

用法示例

 $("#text_box_selector").liveUpdate("#list_selector"); 

注意#list_selector必须找到包含li元素的元素

插件+排序+现场演示

 // https://github.com/joshaven/string_score String.prototype.score = function (word, fuzziness) { 'use strict'; // If the string is equal to the word, perfect match. if (this === word) { return 1; } //if it's not a perfect match and is empty return 0 if (word === "") { return 0; } var runningScore = 0, charScore, finalScore, string = this, lString = string.toLowerCase(), strLength = string.length, lWord = word.toLowerCase(), wordLength = word.length, idxOf, startAt = 0, fuzzies = 1, fuzzyFactor, i; // Cache fuzzyFactor for speed increase if (fuzziness) { fuzzyFactor = 1 - fuzziness; } // Walk through word and add up scores. // Code duplication occurs to prevent checking fuzziness inside for loop if (fuzziness) { for (i = 0; i < wordLength; i+=1) { // Find next first case-insensitive match of a character. idxOf = lString.indexOf(lWord[i], startAt); if (idxOf === -1) { fuzzies += fuzzyFactor; } else { if (startAt === idxOf) { // Consecutive letter & start-of-string Bonus charScore = 0.7; } else { charScore = 0.1; // Acronym Bonus // Weighing Logic: Typing the first character of an acronym is as if you // preceded it with two perfect character matches. if (string[idxOf - 1] === ' ') { charScore += 0.8; } } // Same case bonus. if (string[idxOf] === word[i]) { charScore += 0.1; } // Update scores and startAt position for next round of indexOf runningScore += charScore; startAt = idxOf + 1; } } } else { for (i = 0; i < wordLength; i+=1) { idxOf = lString.indexOf(lWord[i], startAt); if (-1 === idxOf) { return 0; } if (startAt === idxOf) { charScore = 0.7; } else { charScore = 0.1; if (string[idxOf - 1] === ' ') { charScore += 0.8; } } if (string[idxOf] === word[i]) { charScore += 0.1; } runningScore += charScore; startAt = idxOf + 1; } } // Reduce penalty for longer strings. finalScore = 0.5 * (runningScore / strLength + runningScore / wordLength) / fuzzies; if ((lWord[0] === lString[0]) && (finalScore < 0.85)) { finalScore += 0.15; } return finalScore; }; // http://ejohn.org/apps/livesearch/jquery.livesearch.js jQuery.fn.liveUpdate = function(list) { list = jQuery(list); if (list.length) { var rows = list.children('li'), cache = rows.map(function() { return this.innerHTML.toLowerCase(); }); this .keyup(filter).keyup() .parents('form').submit(function() { return false; }); } return this; function filter() { var term = jQuery.trim(jQuery(this).val().toLowerCase()), scores = []; if (!term) { rows.show(); } else { rows.hide(); cache.each(function(i) { var score = this.score(term); if (score > 0) { scores.push([score, i]); } }); jQuery.each(scores.sort(function(a, b) { return b[0] - a[0]; }), function() { jQuery(rows[this[1]]).show(); }); } } }; $("#search").liveUpdate("#colors"); 
  
  • Cat Book
  • Dog Basket
  • Bear Cub
  • Car Door
  • Another option
  • Another Animal
 // Just a shorter version $('ul>li').hide().has(':contains(' + needle + ')').show(); // case insensitive searching with animation $("ul>li").slideUp().filter( function() { return $(this).text().toLowerCase().indexOf(needle) > -1 }).stop(true).fadeIn();