【问题标题】:How do you search a nested list with jQuery?如何使用 jQuery 搜索嵌套列表?
【发布时间】:2012-04-12 22:03:19
【问题描述】:

我已经将一个简单的搜索字段放在一起来查看列表,但是我有嵌套列表并且它仅限于单级列表 - 你如何修改

我把它放在了小提琴中; http://jsfiddle.net/marksweb/4CJMe/

如果结果存在,我需要对我的if(filter) 执行什么操作才能同时检查嵌套项并且不隐藏嵌套列表的子项?

演示站点; http://dl.dropbox.com/u/3755926/cssTricks/main.html

(function ($) {
  // custom css expression for a case-insensitive contains()
  jQuery.expr[':'].Contains = function(a,i,m){
      return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase())>=0;
  };

  function searchList(header, list) { // header is any element, list is an unordered list
    // create and add the filter form to the header
    var form = $("<form>").attr({"class":"filterform","action":"#"}),
        input = $("<input>").attr({"class":"filterinput","type":"text"});
    $(form).append(input).prependTo(header);

    $(input)
      .change( function () {
        var filter = $(this).val();
        if(filter) {
            // this finds all links in a list that contain the input,
            // and hide the ones not containing the input while showing the ones that do
            $(list).find("a:not(:Contains(" + filter + "))").parent().slideUp();
            $(list).find("a:Contains(" + filter + ")").parent().slideDown();
        } else {
            // return to default
            $(list).find("li").slideDown();
        }
        return false;
      })
    .keyup( function () {
        // fire the above change event after every letter
        $(this).change();
    });
  }

  //ondomready
  $(function () {
    searchList($("#main"), $("#contents-list"));
  });
}(jQuery));

【问题讨论】:

  • 我最终修复了它(但我不能回答我自己的问题)。将事情提升到查找 li 然后返回查找 ul 已经修复了看起来的问题。

标签: jquery list search


【解决方案1】:

搜索有效,但仅当文本框失去焦点或按下回车时。

更改以下行:

$(input).change(function(){

到:

$(input).keyup(function(){

而且功能似乎开始正常工作了。

我还注意到 contains 修改没有执行不区分大小写的搜索,因此修改以下行也应该可以解决这个问题:

var hasMatch = searchTerms.length == 0 || $(this).text().toLowerCase().indexOf(searchTerms.toLowerCase()) > 0;

这是更新后的jsFiddle

【讨论】:

  • 谢谢。该更改/键位是更改为新方法的后果。我必须遗漏一些东西,因为虽然它在 jsFiddle 中工作,但当我运行本地文件或公共保管箱 url 时它不起作用。这可能与浏览器安全和运行 JS 有关吗?
  • 据我所知。我刚刚将 jsFiddle 复制到了本地文件中,一切似乎都对我来说运行良好。页面上是否还有其他可能与上述任何内容冲突的内容?
  • 也许吧。这是我有限的知识无济于事的地方。该页面使用 HTML 框架(不幸的是),它位于边栏中,但我看不到任何会导致问题的东西,除非框架本身这样做。这是该网站的演示 - dl.dropbox.com/u/3755926/cssTricks/main.html
  • 老实说,我对镜框的了解也有些晦涩,但我进行了快速镜框测试,结果也很好。 JS 文件是否被正确访问以处理本地文件?
  • 真的不确定,我可以在演示中看到 keyup 事件是如何没有触发的,但是当您将国家示例放入其中时,效果很好。我有点跺脚,tbh。也许尝试模仿他们定义change()keyup() 事件的方式?
【解决方案2】:

教程中的示例非常好,但不适用于我的嵌套列表。我根据示例创建了不同的代码,效果很好。

例如。列表(html代码):

  <h3 id="header">Search words
            <form class="filterform" action="#">
                <input class="filterinput" type="text" id="filterinput">
            </form>
        </h3>
<ul id="list"  >
            <li><span><a>1</a></span>
                <ul>
                    <li><span><a>12</a></span>
                        <ul>
                            <li><span><a>23</a></span>
                                <ul>
                                    <li><span><a>33</a></span></li>
                                    <li><span><a>31</a></span></li>
                                    <li><span><a>35</a></span></li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                    <li><span><a>14</a></span>
                        <ul>
                            <li><span><a>23</a></span>
                                <ul>
                                    <li><span><a>34</a></span></li>
                                    <li><span><a>36</a></span></li>
                                </ul>
                            </li>
                            <li><span><a>24</a></span>
                                <ul>
                                    <li><span><a>32</a></span></li>
                                    <li><span><a>34</a></span></li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li><span><a>2</a></span></li>
        </ul>

这是jquery代码:

    (function ($) {
    // custom css expression for a case-insensitive contains()
    jQuery.expr[":"].contains = jQuery.expr.createPseudo(function (arg) {
        return function (elem) {
            return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
        };
    });

    // this function calls itself, to search in every level
    function hasChild(list) {
        // the searched value
        var filter = $('#filterinput').val();
        // for every children, do function:
        list.children('li').each(function () {
            // see if the list contains the filter
// if you don't want to use span,  you can  write the following function:
 //find("a:contains(" + filter + ")")
                        if ($(this).find("span > a:contains(" + filter + ")").length > 0) {
                            // see if it has nested levels
                            if ($(this).find('ul :first').length > 0) {
                                $(this).show();
                                // recall function
                                hasChild($(this).find('ul :first').parent());
                            } else {
                                $(this).show();
                            }
                        } else {
                            $(this).hide();
                        }
                    });
                };
                $('#filterinput').keyup(function () {
                    // the id of the filtered list
                    var list = '#list';
                    // the searched value
                    var filter = $('#filterinput').val();
                    if (filter) {
                        // call previous function
                        hasChild($(list));
                    } else {
                        // show all
                        $(list).find("li").show();
                    }
                    return false;
                });
            }(jQuery));

【讨论】:

    【解决方案3】:

    我现在已经设法解决了这个问题。

    我在尝试访问我的列表时遇到的最初问题是,我无法对导出的 HTML 中的现有内容使用类选择器,因此我必须添加自定义 ID 并将这些 ID 与 searchList($("#main"), $("#contents-list")); 一起使用,它成功运行。

    然后要访问嵌套列表项,我必须将过滤器级别从 &lt;a&gt;&lt;li&gt; 提升到我的问题中看到的此处以访问 &lt;li&gt; 并默认为 &lt;ul&gt; 所以最终过滤器看起来像这个;

            if(filter) {
                // this finds all links in a list that contain the input,
                // and hide the ones not containing the input while showing the ones that do
                $(list).find("li:not(:Contains(" + filter + "))").parent().slideUp();
                $(list).find("li:Contains(" + filter + ")").parent().slideDown();
            } else {
                // return to default
                $(list).find("ul").slideDown();
            }
            return false;
          })
    

    【讨论】:

      猜你喜欢
      • 2019-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 2014-12-18
      • 1970-01-01
      相关资源
      最近更新 更多