jQuery插件来过滤li元素列表

时间:2015-07-06 14:55:09

标签: javascript jquery html css

这是一个过滤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元素不是。为什么呢?

3 个答案:

答案 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">

liveFilterli下注册#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);
    });
    ...

实例:http://jsfiddle.net/56xsvosq/