这是一个过滤li元素的插件。
jquery.livefilter.js :
/*
* jQuery.liveFilter
*
* Copyright (c) 2009 Mike Merritt
*
* Forked by Lim Chee Aun (cheeaun.com)
*
*/
(function($){
$.fn.liveFilter = function(inputEl, filterEl, options){
var defaults = {
filterChildSelector: null,
filter: function(el, val){
return $(el).text().toUpperCase().indexOf(val.toUpperCase()) >= 0;
},
before: function(){},
after: function(){}
};
var options = $.extend(defaults, options);
var el = $(this).find(filterEl);
if (options.filterChildSelector) el = el.find(options.filterChildSelector);
var filter = options.filter;
$(inputEl).keyup(function(){
var val = $(this).val();
var contains = el.filter(function(){
return filter(this, val);
});
var containsNot = el.not(contains);
if (options.filterChildSelector){
contains = contains.parents(filterEl);
containsNot = containsNot.parents(filterEl).hide();
}
options.before.call(this, contains, containsNot);
contains.show();
containsNot.hide();
if (val === '') {
contains.show();
containsNot.show();
}
options.after.call(this, contains, containsNot);
});
}
})(jQuery);
HTML :
<!DOCTYPE html>
<meta charset="utf-8">
<script src="jquery.min.js"></script>
<script src="jquery.livefilter.js"></script>
<script>
$(function(){
$('#livefilter-list').liveFilter('#livefilter-input', 'li', {
filterChildSelector: 'a'
});
});
</script>
<div>
<fieldset>
<legend><label for="livefilter-input">Search...</label></legend>
<input id="livefilter-input" type="text" value="">
<ul id="livefilter-list">
<li><a href="#">cool</a></li>
<li><a href="#">nice</a></li>
<li><a href="#">interesting</a></li>
<li><a href="#">javascript</a></li>
<li><a href="#">css</a></li>
<li><a href="#">html</a></li>
<li><a href="#">script</a></li>
<li><a href="#">international</a></li>
</ul>
</fieldset>
</div>
这段代码效果很好,但只能使用静态li元素,比如那里的li标签。 我有一个jQuery函数,附加到ul标签很多li元素。但是,在这种情况下,不起作用
我的代码:
<div id="users" class="nav nav-second-level">
<ul id="livefilter-list" aria-expanded="true">
<li><a>Ciao</a></li>
<li><a>Come</a></li>
<li><a>Stai</a></li>
</ul>
</div>
jQuery的:
for (var i in arr) {
$('#users').append('<li data-user="' + arr[i].id + '"><a href="#" style="color: black">' + arr[i].name + '</a></li>');
}
我该如何解决?
更新
<ul id="livefilter-list" class="nav nav-second-level" aria-expanded="true">
<li><a>Hey</a></li>
<li><a>How are</a></li>
<li><a>you?</a></li>
</ul>
我追加其他li元素:
for (var i in arr) {
$('#livefilter-list').append('<li data-user="' + arr[i].id + '"><a href="#" style="color: black">' + arr[i].name + '</a></li>');
}
然后:
$(function () {
$('#livefilter-list').liveFilter('#livefilter-input', 'li', {
filterChildSelector: 'a'
});
});
用“嘿”,“怎么样”和“你?”作品。但是使用jQuery添加的li元素不是。为什么呢?
答案 0 :(得分:1)
由于ul
为#livefilter-list
,您应该使用:
for (var i in arr) {
$('#livefilter-list').append('<li data-user="' + arr[i].id + '"><a href="#" style="color: black">' + arr[i].name + '</a></li>');
}
因此它会li
追加到<ul id="livefilter-list" aria-expanded="true">
,而非<div id="users" class="nav nav-second-level">
当liveFilter
在li
下注册#livefilter-input
时,您无法对#user > li
生效,#livefilter-input
成为jQuery.liveFilt
的兄弟。
编辑:
源代码为 var el = $(this).find(filterEl);
if (options.filterChildSelector) el = el.find(options.filterChildSelector);
,
li
它会在创建时缓存元素,并且不再监视监视目标的进一步添加/删除,因此它不会过滤掉初始化后添加的任何 var el = $(this).find(filterEl);
if (options.filterChildSelector) el = el.find(options.filterChildSelector);
var self = this;
var filter = options.filter;
$(inputEl).keyup(function(){
el = $(self).find(filterEl);
if (options.filterChildSelector) el = el.find(options.filterChildSelector);
var val = $(this).val();
var contains = el.filter(function(){
return filter(this, val);
});
var containsNot = el.not(contains);
if (options.filterChildSelector){
contains = contains.parents(filterEl);
containsNot = containsNot.parents(filterEl).hide();
}
options.before.call(this, contains, containsNot);
contains.show();
containsNot.hide();
if (val === '') {
contains.show();
containsNot.show();
}
options.after.call(this, contains, containsNot);
。
您可以调整其代码以强制它在过滤器即将发生时获取最新元素:
EMFILE error
所以现在它有效。见Demo
答案 1 :(得分:1)
此语法:
$(function (){...});
在加载dom后立即执行参数传递的匿名函数。这意味着:
function () {
$('#livefilter-list').liveFilter('#livefilter-input', 'li', {
filterChildSelector: 'a'
}
在for循环中将元素添加到livefilter-list之前运行:
for (var i in arr) {
$('#livefilter-list').append('<li data-user="' + arr[i].id + '"><a href="#" style="color: black">' + arr[i].name + '</a></li>');
}
我建议您在将元素附加到livefilter-list后尝试调用liveFilter:
for (var i in arr) {
$('#livefilter-list').append('<li data-user="' + arr[i].id + '"><a href="#" style="color: black">' + arr[i].name + '</a></li>');
}
$('#livefilter-list').liveFilter('#livefilter-input', 'li', {
filterChildSelector: 'a'
});
答案 2 :(得分:0)
您只能找到一次过滤器元素:
var el = $(this).find(filterEl);
if (options.filterChildSelector) el = el.find(options.filterChildSelector);
稍后,在keyup
上,您使用此变量el
进一步过滤元素,但是如果您在初始化插件和按键之间添加了任何新li
,则新元素未包含在预定义列表el
中。
答案是在每个keyup
上查找实时元素,而不是将其缓存在变量中。
这应该像在函数中包含上面两行一样简单:
function getFilterElements(){
var el = $(this).find(filterEl);
if (options.filterChildSelector) el = el.find(options.filterChildSelector);
return el;
}
稍后在keyup
中调用
var self = this;
$(inputEl).keyup(function(){
var val = $(this).val();
var el = getFilterElements.call(self)
var contains = el.filter(function(){
return filter(this, val);
});
...