2012-01-04 39 views
2

http://jsfiddle.net/nicktheandroid/QhL2M/ (類型「再見」到輸入框「)劇本的不報真當我覺得應該,而不是報告全是假的

目的:每個li包含在它的標籤的話當用戶類型。 input框中的這些標籤字中的一個,它將隱藏所有不包含該標籤字的li。如果多於1個li的標籤字匹配任何字,則可以在input中鍵入多個字在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中看到我想要做的事情並知道如何幫助我,那太棒了。我試圖通過這種方式工作,因爲還有一些東西需要改變。

+0

匹配全局變量嗎?可以被覆蓋。您是否嘗試過在正則表達式後面放置調試器語句並檢查匹配的值? – sissonb 2012-01-05 00:00:10

回答

2

我認爲問題是,你通過所有列表中的項目與循環:

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

然後在每次迭代中循環顯示單詞列表:

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

,然後在循環再次處理所有 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已經被初始化以保存該輸入的文本。我上面的代碼和demo已經更新。

+0

哦,你真棒。你真的瞭解我,並且確切地知道該怎麼做,這很美麗。有一件事我注意到,但我無法弄清楚:是在第一個單詞之後,我點擊空格或逗號,它會再次顯示整個列表。我無法讓它繼續只顯示李的匹配。因此,當新的li被匹配,或者用戶刪除了一個單詞的單詞/字母(導致該單詞不再匹配)時,用戶只能看到列表animate/show/hide,這是否有意義? – 2012-01-05 08:33:12

+0

我已經稍微更新了我的答案(包括更新的小提琴的鏈接)。問題在於,當空格或逗號是最後一項時(或者如果您在一行中輸入了多個空格或逗號)分隔輸入時,inputwords數組中的空字符串結束,因此圍繞這些空字符串形成的正則表達式項目清單。所以我添加了一行'if($ .trim(a_filter)===「」)return;'噹噹前項目爲空時,跳到'$ .each'的下一個迭代。 – nnnnnn 2012-01-05 09:37:30

+0

哦,當我在它時,我將正則表達式聲明更改爲不區分大小寫,因爲否則(因爲您將搜索字符串更改爲小寫)它不匹配大寫字母。試試我更新的小提琴。 – nnnnnn 2012-01-05 09:38:47

0

讓我知道這是你試圖完成什麼(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)); 
相關問題