Giả sử, chúng ta có một mảng các đối tượng như thế này -
const arr = [ { id: '1', name: 'name 1', parentId: null }, { id: '2', name: 'name 2', parentId: null }, { id: '2_1', name: 'name 2_1', parentId: '2' }, { id: '2_2', name: 'name 2_2', parentId: '2' }, { id: '3', name: 'name 3', parentId: null }, { id: '4', name: 'name 4', parentId: null }, { id: '5', name: 'name 5', parentId: null }, { id: '6', name: 'name 6', parentId: null }, { id: '7', name: 'name 7', parentId: null }, { id: '1_1', name: 'name 1_1', parentId: '1' }, { id: '1_2', name: 'name 1_2', parentId: '1' }, { id: '1_3', name: 'name 1_3', parentId: '1' }, { id: '1_4', name: 'name 1_4', parentId: '1' }, { id: '1_5', name: 'name 1_5', parentId: '1' }, { id: '2_1_1', name: 'name 2_1_1', parentId: '2_1' }, { id: '2_1_2', name: 'name 2_1_2', parentId: '2_1' }, { id: '2_1_3', name: 'name 2_1_3', parentId: '2_1' }, { id: '2_1_4', name: 'name 2_1_4', parentId: '2_1' }, { id: '2_1_5', name: 'name 2_1_5', parentId: '2_1' }, ];
Chúng tôi được yêu cầu viết một hàm JavaScript có trong một mảng các đối tượng như vậy. Sau đó, hàm sẽ xây dựng một cấu trúc dữ liệu dạng cây dựa trên mảng này liên kết các phần tử con với đối tượng mẹ của chúng và hiển thị kết quả trên màn hình ở định dạng danh sách lồng nhau.
Ví dụ
Mã cho điều này sẽ là -
Mã HTML -
<html> <head></head> <body> <div id = "tree"> </div> </body> </html>
Mã JavaScript -
const arr = [ { id: '1', name: 'name 1', parentId: null }, { id: '2', name: 'name 2', parentId: null }, { id: '2_1', name: 'name 2_1', parentId: '2' }, { id: '2_2', name: 'name 2_2', parentId: '2' }, { id: '3', name: 'name 3', parentId: null }, { id: '4', name: 'name 4', parentId: null }, { id: '5', name: 'name 5', parentId: null }, { id: '6', name: 'name 6', parentId: null }, { id: '7', name: 'name 7', parentId: null }, { id: '1_1', name: 'name 1_1', parentId: '1' }, { id: '1_2', name: 'name 1_2', parentId: '1' }, { id: '1_3', name: 'name 1_3', parentId: '1' }, { id: '1_4', name: 'name 1_4', parentId: '1' }, { id: '1_5', name: 'name 1_5', parentId: '1' }, { id: '2_1_1', name: 'name 2_1_1', parentId: '2_1' }, { id: '2_1_2', name: 'name 2_1_2', parentId: '2_1' }, { id: '2_1_3', name: 'name 2_1_3', parentId: '2_1' }, { id: '2_1_4', name: 'name 2_1_4', parentId: '2_1' }, { id: '2_1_5', name: 'name 2_1_5', parentId: '2_1' }, ] const tree = document.getElementById("tree") arr.forEach(a => { const div = document.createElement("div") if (a.parentId === null) { div.classList.add("parent") div.setAttribute("id", `id${a.id}`) div.innerText = a.name tree.appendChild(div) } else { const parent = document.getElementById(`id${a.parentId}`) if (!parent.classList.contains("parent")) { parent.classList.add("parent") } console.log(`${a.id} `, parent) let childContainer = null if (parent.childElementCount === 0) { childContainer = document.createElement("div") childContainer.classList.add("childContainer") parent.appendChild(childContainer) childContainer.classList.add("hidden") } else { childContainer = document.querySelector(`#id${a.parentId} .childContainer`) } div.classList.add("child") div.setAttribute("id", `id${a.id}`) div.innerText = a.name childContainer.appendChild(div) } }) const parents = Array.from(document.getElementsByClassName("parent")).filter(p => p.childElementCount !== 0) parents.forEach(p => { p.addEventListener("click", function(e) { e.preventDefault() const container = this.getElementsByClassName("childContainer")[0] container.classList.toggle("visible") e.stopPropagation() }) })
Mã CSS -
.parent, .child { cursor: pointer; } .parent { margin: 10px 0; font-size: 1.3rem; } .parent::before { content: "\25BA"; margin-right: 10px; } .childContainer { margin-left: 20px; display: none; } .childContainer.visible { display: block; } .child { font-size: 1rem; } .child::before { content: "\25BA"; }
Và kết quả trên màn hình sẽ là -