客戶端過濾數據:比較CSS,jQuery和React

假設您有100個名字的列表:css

<ul>
  <li>Randy Hilpert</li>
  <li>Peggie Jacobi</li>
  <li>Ethelyn Nolan Sr.</li> 
  <!-- and then some -->
</ul>

...或文件名或電話號碼,等等。並且您想在客戶端過濾它們,這意味着您沒有在服務器端請求搜索數據並返回結果。您只想輸入「 rand」並使其過濾列表以包括「 Randy Hilpert」和「 Danika Randall」,由於它們中都包含該字符串。其餘全部內容均未包含在結果中。數組

讓咱們看看如何使用不一樣的技術來作到這一點。服務器

CSS能夠八九不離十作到這一點

CSS不能根據它們包含的內容來選擇項目,可是能夠根據屬性和這些屬性的值進行選擇(利用CSS的屬性選擇器)。所以,咱們也將名稱移動到屬性中。ide

<ul>
  <li data-name="Randy Hilpert">Randy Hilpert</li>
  <li data-name="Peggie Jacobi">Peggie Jacobi</li>
  <li data-name="Ethelyn Nolan Sr.">Ethelyn Nolan Sr.</li> 
  ...
</ul>

如今要過濾包含「 rand」的名稱的列表,很是簡單:函數

li {
  display: none;
}

li[data-name*="rand" i] {
  display: list-item;
}

注意第5行的字母「i」。這表示「不區分大小寫」,在這裏很是有用。工具

爲了使此動態化,咱們將與input過濾器一塊兒工做,咱們須要使JavaScript不只對鍵入的過濾器作出反應,並且還要生成與要搜索的內容匹配的CSS。this

假設咱們style在頁面上有一個方塊:spa

<style id="cssFilter">
  /* dynamically generated CSS will be put in here */
</style>

咱們能夠監聽過濾器輸入的更改並生成該CSS:code

filterElement.addEventListener("input", e => {
  let filter = e.target.value;
  let css = filter ? `
    li {
      display: none;
    }
    li[data-name*="${filter}" i] {
      display: list-item;
    }
  ` : ``;
  window.cssFilter.innerHTML = css;
});

請注意,當過濾器爲空時,咱們將清空樣式塊,所以全部結果都會顯示出來。blog

圖片描述

我認可利用CSS作到這一點很奇怪。

jQuery使得它更容易

既然咱們仍然須要JavaScript,也許jQuery是能夠接受的工具。這裏有兩個值得注意的變化:

  • jQuery 能夠根據項目包含的內容來選擇項目。爲此,它具備選擇器API。咱們再也不須要多餘的屬性。
  • 這將全部過濾保持在一種技術上。

咱們仍然會監聽輸入內容的輸入,而後,若是咱們有過濾條件,咱們將隱藏全部列表項,並顯示包含過濾條件的項。不然,咱們將再次顯示全部內容:

const listItems = $("li");

$("#filter").on("input", function() {
  let filter = $(this).val();
  if (filter) {
    listItems.hide();
    $(`li:contains('${filter}')`).show();
  } else {
    listItems.show();
  }
});

使過濾器不區分大小寫比CSS更加費事,可是咱們能夠經過覆蓋默認方法來作到這一點:

jQuery.expr[':'].contains = function(a, i, m) {
  return jQuery(a).text().toUpperCase()
      .indexOf(m[3].toUpperCase()) >= 0;
};

圖片描述

在React中可使用狀態跟Filter函數作到這一點

在React中沒有作到這一點的真正方法,但我認爲將名稱列表保留爲數據(如Array),映射它們並僅呈現所需內容是React-y。輸入中的更改會過濾數據自己,並在須要時從新渲染React。

若是有一個names = [array, of, names],咱們能夠很容易地對其進行過濾:

filteredNames = names.filter(name => {
  return name.includes(filter);
});

此次,能夠這樣區分大小寫:

filteredNames = names.filter(name => {
  return name.toUpperCase().includes(filter.toUpperCase());
});

而後,咱們將執行.map()JSX中的典型操做來遍歷數組並輸出名稱。

圖片描述

我沒有任何特別的偏好

這不是您選擇技術的目的。您可使用現有技術進行操做。我也不認爲任何一種方法在技術債務方面都比其餘方法特別重。

相關文章
相關標籤/搜索