首頁 >web前端 >js教程 >建立具有排序功能的啟用 JavaScript 的 HTML 表

建立具有排序功能的啟用 JavaScript 的 HTML 表

王林
王林原創
2023-09-09 13:37:011289瀏覽

在網站上顯示資料時,重要的是提供使用戶更輕鬆瀏覽資料的功能。其中一項功能就是能夠對資料進行排序。

對資料進行排序是指將資料依照指定的值,依升序或降序排列。我們可以使用 JavaScript 在網站的客戶端手動處理資料排序。如果您正在開發靜態網站或消除伺服器中資料排序的負擔,這尤其有用。

在本教學中,我們將使用 JavaScript 將模擬 JSON 回應中的資料顯示到 HTML 表中。我們還將包含使表格可根據表標題中的值進行排序的功能。

這是成品。點擊任何表格標題即可對表格進行相應排序。

1. 用 HTML 放置內容

f5d188ed2c074f8b944552db028f98a1 標籤是用於在網頁上顯示資料的語意 HTML 標籤。我們將把 f5d188ed2c074f8b944552db028f98a1 標籤放置在表格容器 div 中,這將允許我們在 CSS 中包含一些響應式樣式。

<div class="table-container">
  <table class="data-table">
  </table>
</div>

我們的表格將包含表格頭、thead 和表格內容、tbody 標籤。在表頭中,我們將在每個 th 單元格中包含按鈕,這些按鈕將用於處理排序功能。表格內容的儲存格將使用我們的 JSON 回應中的資料透過 JavaScript 新增。

<div class="table-container">
  <table class="data-table">
    <thead>
      <tr>
        <th><button id="name">Name</button></th>
        <th><button id="type">Type</button></th>
        <th><button id="hp">HP</button></th>
        <th><button id="attack">Attack</button></th>
        <th><button id="defense">Defense</button></th>
        <th><button id="spAttack">Sp. Attack</button></th>
        <th><button id="spDefense">Sp. Defense</button></th>
        <th><button id="speed">Speed</button></th>
        <th><button id="total">Total</button></th>
      </tr>
    </thead>
    <tbody id="table-content"></tbody>
  </table>
</div>

2.用CSS製作響應式表格

使用 HTML 表格的更常見問題之一是缺乏回應能力。該表格可能存在儲存格重疊問題或超出整頁的邊界。

我們可以透過將表格放置在具有溢出滾動屬性的整頁寬度的表格容器中來解決這些問題。這樣,表格始終只與整頁一樣寬,並且由於可滾動溢出而無需縮小單元格。我們還將在表格單元格中包含最小寬度屬性,以避免文字換行。

创建具有排序功能的启用 JavaScript 的 HTML 表

#這是讓我們的表格可捲動所需的 CSS:

.table-container {
  width: 100%;
  overflow: scroll;
}

table {
  width: 100%;
}

然後我們可以加入其餘的樣式:

.table-container {
  margin: auto;
  max-width: 1200px;
  min-height: 100vh;
  overflow: scroll;
  width: 100%;
}

table {
  border-collapse: collapse;
  width: 100%;
}

thead tr {
  border-bottom: 1px solid #ddd;
  border-top: 1px solid #ddd;
  height: 1px;
}

th {
  font-weight: bold;
  height: inherit;
  padding: 0;
}

th:not(:first-of-type) {
  border-left: 1px solid #ddd;
}

th button {
  background-color: #eee;
  border: none;
  cursor: pointer;
  display: block;
  font: inherit;
  height: 100%;
  margin: 0;
  min-width: max-content;
  padding: 0.5rem 1rem;
  position: relative;
  text-align: left;
  width: 100%;
}

tbody tr {
  border-bottom: 1px solid #ddd;
}

td {
  padding: 0.5rem 1rem;
  text-align: left;
}

3. 將 JSON 資料放入 HTML 表格

對於此範例,我們將使用模擬解析的 JSON 回應。這就是我們的數據:

const response = {
   "pokedata": [
      {
         "name": "Bulbasaur",
         "type": "Grass",
         "hp": 45,
         "attack": 49,
         "defense": 49,
         "spAttack": 65,
         "spDefense": 65,
         "speed": 45,
         "total": 318
      },
      ...
   ]
}

我們將把資料放在 0bf74e530db83faaf52a6e1c5b166355 標記中,以便我們在 JavaScript 中定位該元素;

const tableContent = document.getElementById("table-content")

行內容將基於 response.pokedata 中的每個物件。讓我們定義一個函數來根據物件資料建立新行:

const createRow = (obj) => {
  const row = document.createElement("tr");
  const objKeys = Object.keys(obj);
  objKeys.map((key) => {
    const cell = document.createElement("td");
    cell.setAttribute("data-attr", key);
    cell.innerHTML = obj[key];
    row.appendChild(cell);
  });
  return row;
};

在此函數中,我們使用 Object.keys() 方法以陣列形式取得物件鍵。傳回值如下所示:

创建具有排序功能的启用 JavaScript 的 HTML 表

#一旦我們獲得了物件鍵的數組,我們就使用 .map() 方法循環遍歷每個鍵。 map 方法對陣列中的每個項目執行我們傳遞給它的函數。

在此映射函數中,我們為數組中的每個項目建立一個新單元格,並將單元格的 innerHTML 設定為對應的物件鍵值。

创建具有排序功能的启用 JavaScript 的 HTML 表

#最後,我們使用 .appendChild() 方法將建立的單元格附加到函數開頭定義的行。

現在我們有了行建立函數,我們將定義一個函數來循環 response.pokedata 陣列並將每個新行附加到我們的 tableContent 元素。

const getTableContent = (data) => {
  data.map((obj) => {
    const row = createRow(obj);
    tableContent.appendChild(row);
  });
};

我們會將 getTableContent 函數傳遞到事件偵聽器中,以便在頁面載入後將內容新增到表中。

window.addEventListener("load", () => {
  getTableContent(response.pokedata);
});

4. 使用 JavaScript 對資料進行排序

現在我們已經建立了表格,讓我們加入排序功能。在我們的 HTML 中,我們在標題單元格中包含了按鈕,這些按鈕以物件鍵作為其 id。現在讓我們定位這些按鈕:

const tableButtons = document.querySelectorAll("th button");

我們希望根據單擊的按鈕對資料進行排序,並且還包含一個在單擊按鈕時切換排序方向(升序或降序)的功能。

我們可以使用 .sort() 方法來處理 response.pokedata 陣列中的資料排序。 sort 方法接受一個比較兩個不同參數的函數,並根據函數回應對它們進行排序:

compareFunction(a, b) 返回值 排序顺序
> 0 排序 a 之后 b
< 0 a 排序在 b 之前
=== 0 保持 ab 的原始顺序

来源:MDN

关于排序方法需要注意的另一件事是它会改变它所操作的原始数组。这意味着它改变了我们原始数组的值。

创建具有排序功能的启用 JavaScript 的 HTML 表

我们可以通过使用扩展语法来避免改变原始数组[...]

创建具有排序功能的启用 JavaScript 的 HTML 表

现在我们可以创建排序函数了。这就是我们的排序函数的逻辑:

  1. 清除tableContent元素中的内容
  2. 根据所选参数和方向对数据进行排序
  3. 使用 getTableContent 函数将排序后的数据附加到我们的 tableContent
const sortData = (data, param, direction = "asc") => {
  tableContent.innerHTML = '';
  const sortedData =
    direction == "asc"
      ? [...data].sort(function (a, b) {
          if (a[param] < b[param]) {
            return -1;
          }
          if (a[param] > b[param]) {
            return 1;
          }
          return 0;
        })
      : [...data].sort(function (a, b) {
          if (b[param] < a[param]) {
            return -1;
          }
          if (b[param] > a[param]) {
            return 1;
          }
          return 0;
        });

  getTableContent(sortedData);
};

我们的排序函数需要三个参数:

  • data:待排序的数组
  • param:用于对数组进行排序的值
  • direction:按升序或降序对数组进行排序。默认参数值设置为“asc”。

我们通过将innerHTML 设置为空白字符串来清除tableContent 元素中的内容。然后,我们使用 .sort() 方法和 direction 参数来确定数据应如何排序。我们反转比较函数以便按降序排序。通过这种方式使用比较函数,我们可以对数据进行排序,而不管值的类型(字符串、整数、浮点数等)

最后,我们将 sortedData 作为表内容中的新值传递。

现在,我们将排序函数传递到表格按钮的单击事件侦听器中,并处理切换排序方向。

window.addEventListener("load", () => {
  getTableContent(response.pokedata);

  [...tableButtons].map((button) => {
    button.addEventListener("click", (e) => {
        
      if (e.target.getAttribute("data-dir") == "desc") {
        sortData(response.pokedata, e.target.id, "desc");
        e.target.setAttribute("data-dir", "asc");
      } else {
        sortData(response.pokedata, e.target.id, "asc");
        e.target.setAttribute("data-dir", "desc");
      }
      
    });
  });
});

在此函数中,我们通过在按钮上设置 data-dir 属性来处理切换以确定排序方向。我们还将更新 CSS 以根据排序方向在按钮旁边显示一个图标:

th button::after {
  position: absolute;
  right: 0.5rem;
}

th button[data-dir="asc"]::after {
  content: url("data:image/svg+xml,%3Csvg xmlns='https://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpolygon points='0, 0 8,0 4,8 8' fill='%23818688'/%3E%3C/svg%3E");
}

th button[data-dir="desc"]::after {
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpolygon points='4 0,8 8,0 8' fill='%23818688'/%3E%3C/svg%3E");
}

我们不想让图标显示在所有以前单击的按钮上,因此我们将定义一个 resetButtons 函数,该函数删除任何未单击的按钮上的 data-dir 属性。

const resetButtons = (event) => {
  [...tableButtons].map((button) => {
    if (button !== event.target) {
      button.removeAttribute("data-dir");
    }
  });
};

我们会将该函数传递到按钮事件侦听器中,以便在单击新按钮时重置以前的按钮

window.addEventListener("load", () => {
  getTableContent(response.pokedata);

  [...tableButtons].map((button) => {
    button.addEventListener("click", (e) => {
        
      resetButtons(e);
      
      if (e.target.getAttribute("data-dir") == "desc") {
        sortData(response.pokedata, e.target.id, "desc");
        e.target.setAttribute("data-dir", "asc");
      } else {
        sortData(response.pokedata, e.target.id, "asc");
        e.target.setAttribute("data-dir", "desc");
      }
      
    });
  });
});

结论

这样,我们就完成了!我们仅使用普通 JavaScript 创建了一个可排序的表格!

以上是建立具有排序功能的啟用 JavaScript 的 HTML 表的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn