【问题标题】:Not reporting true when I think it should, instead reporting all false在我认为应该报告的时候不报告真实,而是报告所有错误
【发布时间】:2012-01-04 23:43:14
【问题描述】:

http://jsfiddle.net/nicktheandroid/QhL2M/ (在输入框中输入“再见”)

脚本的目的:每个li 都包含标签词。当用户在input 框中键入这些标记词之一时,它将隐藏所有不包含该标记词的li。可以在input 中输入多个单词,如果超过 1 个li 的标记词与input 中的任何单词匹配,则显示它们。所以它基本上是一个允许多个单词的过滤列表,并显示所有匹配的li,其中包含输入input 的任何单词。它只匹配整个单词,而不是部分单词,并且它应该只在匹配另一个完整单词时更新匹配列表(当多个单词时)。这就是目标。

我的问题是它错误地报告了这段代码中有匹配项:

 if (matches == true) {
    alert('matched true')  //incorrectly reports  
 } else {
    alert('matched false') //incorrectly reports  
 }

当这段代码正确报告时:

if (regex.test($(this).text()) === true) {
    matches = true;
    // alert('tis true') //correctly reports  
} else {
       matches = false;
       // alert('tis false') //correctly reports   
}

为什么报告不正确? (正确,如:我希望它报告的内容)

如果有人在 Javascript 方面足够好,可以看到我正在尝试做什么并知道如何帮助我,那就太好了。我正在努力解决这个问题,因为只有几件事需要改变。

【问题讨论】:

  • 是否匹配全局变量?可以被覆盖。您是否尝试过将调试器语句放在正则表达式之后并检查匹配项的值?

标签: javascript jquery filter


【解决方案1】:

我认为问题在于您正在遍历所有列表项:

$("#list li").each(function() {

然后在每次迭代中,您循环遍历单词列表:

$.each(inputWords, function(i, a_filter) {

然后在 inner 循环中再次处理 all li 元素:

var containing = $('#list li').filter(function () {

那么在内心深处,你对你正在处理的事情感到困惑。我认为您需要做的是遍历每个元素,测试它是否与输入单词列表匹配,然后根据需要隐藏或显示该元素。像这样的:

var inputWords = inputValue.toLowerCase().split(/[\s,]+/);

$("#list li").each(function() {
    var matches = false,
        $currentElement = $(this);

    $.each(inputWords, function(i, a_filter) {
        if ($.trim(a_filter)==="") return; // skip blank items

        var regex = new RegExp('\\b(' + a_filter + ')(s|es|\'s)?\\b', 'i');
        if (regex.test($currentElement.text())) {
            matches = true;
            return false;  // return false breaks out of the $.each
                           // (no need to continue once a match is found)
        }
     });

     if (matches)
        $currentElement.slideDown(400);
     else
        $currentElement.slideUp();
});

工作演示:http://jsfiddle.net/QhL2M/19/

编辑:您拆分输入单词列表的方式也不适合我:

var inputWords = $('.filterinput').text().toLowerCase().split(/[\s,]+/);
// I've changed that to
var inputWords = inputValue.toLowerCase().split(/[\s,]+/);

您不想在输入上使用.text(),无论如何inputValue 已经在之前初始化以保存该输入的文本。我上面的代码和演示已经更新。

【讨论】:

  • 天哪,你太棒了。你实际上了解我并且确切地知道该做什么,这很漂亮。我注意到我无法弄清楚的一件事是:在第一个单词之后我点击空格或逗号,它会再次显示整个列表。我无法让它继续只显示 li 的匹配项。所以用户只有在匹配新的 li 或用户删除单词的单词/字母(导致该单词不再匹配)时才能看到列表 animate/show/hide,这有意义吗?
  • 我已经稍微更新了我的答案(包括更新小提琴的链接)。问题是当您在空格或逗号是最后一项时拆分输入时(或者如果您连续输入多个空格或逗号),您最终会在 inputWords 数组中得到空字符串,因此围绕这些空字符串形成的正则表达式匹配每个项目清单。所以我添加了一行if ($.trim(a_filter)==="") return;,以在当前项目为空时跳到$.each的下一次迭代。
  • 哦,当我这样做时,我将正则表达式声明更改为不区分大小写,因为否则(假设您将搜索字符串更改为小写)它永远不会匹配大写单词。试试我更新的小提琴。
  • 1) 哇,谢谢。近乎完美。如果您能帮我解决最后两个小错误,我将非常感激,如果您没有时间,我理解 - 您帮了我很多。如果您开始在输入框中输入,并且有超过 2 个字符但还没有匹配,它会隐藏所有 LI。有没有办法让所有的 LI 保持可见,直到你有一个匹配,然后 slideUp/slideDown 需要隐藏/显示什么? - 所以用户没有开始输入,然后当甚至没有匹配时所有的 LI 都消失了?
【解决方案2】:

如果这就是你想要完成的事情,请告诉我 (jsFiddle example):

(function($) {
    function fiKeyup() {
        var inputValue = $(this).val();
        if (inputValue.length > 2) {
            var inputWords = inputValue.split(/[\s,]+/ig);
            var containing = $('#list li').filter(function () {
                var ret = false;
                var text = $(this).text().toLowerCase();
                $.each(inputWords, function(i, a_filter) {
                    var regex = new RegExp('\\b(' + a_filter + ')(s|es|\'s)?\\b');
                    if(regex.test(text)) {
                        return !(ret = true);
                    }
                });
                return ret;
            });

            $('#list li').not(containing).slideUp();
        } else {
            $('#list li').slideDown();
        }
        return false;
    };
    var timeout;

    $('.filterInput').keyup(function() {
        var that = this;
        clearTimeout(timeout);
        timeout = setTimeout(function() {
            fiKeyup.call(that);
        }, 500);
    });

}(jQuery));

【讨论】:

    猜你喜欢
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    • 2012-04-03
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    相关资源
    最近更新 更多