簡體   English   中英

如何對表進行排序並使用純JavaScript重新生成它

[英]How to sort the table and re-generate it with help of pure JavaScript

我需要按名稱對表進行排序。 為了排序,我使用該功能

function sortArray(index) {
  let arr = [];
  rows.forEach( elem => {
    arr.push(elem.children[index].textContent); 
  })
  let sort = arr.sort( (a, b) => {
    if ( a > b) {
      return 1;
    }
    if (a < b) {
      return -1;
    }
    return 0;
  });
  console.log(sort);
  return sort;
  }

但我不知道如何重繪表格。 表I動態地從JSON文件創建。 要開始排序,您需要單擊該字段的名稱,然后應顯示已排序的表。

const buildHeader = data =>
  Object.keys(data)
    .map(k => `<th>${k}</th>`)
    .join("");
const buildRow = data =>
  Object.keys(data)
    .map(k => `<td>${data[k]}</td>`)
    .join("");
let element = document.querySelector(".people");

function showPeople(people) {
  let table = document.createElement("table");
  table.classList.add("people__table");
  let thead = document.createElement("thead");
  thead.innerHTML = `<tr class="head">${buildHeader(people[0])}</tr>`;
  table.appendChild(thead);
  let tbody = document.createElement("tbody");
  tbody.innerHTML = people
    .map(p => `<tr class="person">${buildRow(p)}</tr>`)
    .join("");
  table.appendChild(tbody);
  element.appendChild(table);
}

const customPeople = data =>
  data.map((p, i) => {
    return {
      name: p.name,
      sex: p.sex,
      born: p.born,
      died: p.died,
      age: p.died - p.born,
      mother: p.mother,
      father: p.father,
    };
  });

showPeople(customPeople(ANCESTRY_FILE));

像這樣sortTable函數可以完成這項工作:

 function sortTable(tbody, index, ascending) { Array.prototype.slice.call(tbody.children).sort( (tr1, tr2) => tr1.children[index].textContent.localeCompare(tr2.children[index].textContent) * (ascending ? 1 : -1) ).forEach(tr => tbody.appendChild(tr)); } // demonstration (function(){ const thead_tr = document.getElementById('thdtr'); const tbody = document.getElementById('tbd'); function makeCell() { const td = document.createElement('td'); td.appendChild(document.createTextNode(Math.round(Math.random() * 999999999).toString(36))); return td; } function makeRow() { const tr = document.createElement('tr'); for(let i = 0; i < thead_tr.children.length; i++) tr.appendChild(makeCell()); return tr; } // adds click-to-sort functionality Array.prototype.forEach.call(thead_tr.children, (th, index) => { let asc_toggle = false; // false will start off in ascending order th.addEventListener('click', event => sortTable(tbody, index, asc_toggle = !asc_toggle)); }); // fills the table with random alphanumeric data for(let i = 0; i < 100; i++) tbody.appendChild(makeRow()); }()); 
 <table> <thead> <tr id="thdtr"> <th>col 1</th> <th>col 2</th> <th>col 3</th> </tr> </thead> <tbody id="tbd"> </tbody> <table> 

我的sortTable函數是一個通用的就sortTable排序函數,可以在任何表上使用。 它接受3個參數:

  1. tbody - DOMElement - 對tbody元素或table元素本身的引用,以tr (行)元素為准。
  2. index - Number - 要排序的列的索引(從0開始)。
  3. ascending - Boolean - 順序是升序( true )還是降序( false

用於當前代碼的示例用法:

sortTable(document.querySelector('.people__table tbody'), 0, true);

您可以將行重新添加到表體:

 const body = document querySelector(".people__table > tbody");

 for(const el of sort)
   body.appendChild(el);

或者您只是對數據進行排序並重新生成整個表。

請找到以下示例:

 let data = generateData(); let columns = [ { name: "id", callback: function() { flags.id *= -1; doSortInt("id", flags.id); } }, { name: "name", callback: function() { flags.name *= -1; doSortStrings("name", flags.name); } }, { name: "age", callback: function() { flags.age *= -1; doSortInt("age", flags.age); } } ]; var flags = { id: -1, name: -1, age: -1 }; createBasicTable(columns); populateDataToTable(data); function doSortInt(prop, flag) { data.sort(function(a, b) { return flag * (b[prop] - a[prop]); }); populateDataToTable(data); } function doSortStrings(prop, flag) { data.sort(function(a, b) { return flag * ("" + a[prop]).localeCompare(b[prop]); }); populateDataToTable(data); } /** * This function is used to fill in the table with data from array */ function populateDataToTable(data) { let tableBody = document.querySelector("#table-body"); // remove all childs while (tableBody.firstChild) { tableBody.removeChild(tableBody.firstChild); } // add new data data.forEach(function(el) { let tr = document.createElement("tr"); let th1 = document.createElement("th"); th1.innerHTML = el.id; tr.appendChild(th1); let th2 = document.createElement("th"); th2.innerHTML = el.name; tr.appendChild(th2); let th3 = document.createElement("th"); th3.innerHTML = el.age; tr.appendChild(th3); tableBody.appendChild(tr); }); } /** * This function is used to create a basic empty table */ function createBasicTable(columns) { let element = document.querySelector("#table-container"); let table = document.createElement("table"); table.classList.add("people__table"); let thead = document.createElement("thead"); let tr = document.createElement("tr"); columns.forEach(function(col) { let th = document.createElement("th"); th.classList.add("head"); th.innerHTML = col.name; th.addEventListener("click", col.callback); // add listener here tr.appendChild(th); }); thead.appendChild(tr); table.appendChild(thead); let tbody = document.createElement("tbody"); tbody.id = "table-body"; table.appendChild(tbody); element.appendChild(table); } /** * This function is used to generate some data for the table */ function generateData() { let data = []; for (var i = 0; i < 100; i++) { let obj = { id: i, name: "Name_" + (i + 1), age: 30 + i * 2 }; data.push(obj); } return data; } 
 <!DOCTYPE html> <html class="no-js"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title></title> <meta name="description" content="" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> </head> <body> <div id="table-container"></div> </body> </html> 

要點是:

在列定義數組中,您有每個列標題的回調。 然后你調用該函數

createBasicTable

這會創建一個沒有數據的空表。 在此函數中,您將注冊列標題回調。 然后你有一個功能

populateDataToTable

它將數組作為參數並使用此數組來構建表行。 最后,在回調中,您只需要正確排序數據數組並使用函數更新表內容:

populateDataToTable

ps代碼不是完美的,但它至少應該給你一個提示,如何實現這個功能。 我明天會嘗試改進代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM