codeStates front-end/Java Script

[JS] chapter23. Tree UI

ํ™˜ํ…Œํฌ 2023. 2. 14. 20:39
๋ฐ˜์‘ํ˜•

 

 

 

๐Ÿ“Œ  Tree UI

 

 

 

 

๐Ÿ“ ํŠธ๋ฆฌ๊ตฌ์กฐ

 

ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•  ๋•Œ ์žฌ๊ท€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์‹œ

 

 

 

DOM์˜ ๋Œ€ํ•ด ํ•™์Šต ํ›„ ์‹ค์Šต ์ง„ํ–‰

 

 

[JS] chapter11. DOM/DOM ๋‹ค๋ฃจ๊ธฐ(CRUD)

DOM (Document Object Model) HTML ์š”์†Œ๋ฅผ object ์ฒ˜๋Ÿผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋ธ ์ฆ‰, DOM์œผ๋กœ HTML์„ ์กฐ์ž‘ ๊ฐ€๋Šฅํ•˜๋‹ค. HTML์•ˆ์˜ JS ํŒŒ์ผ์„ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด -----------------------------------------------------------------------------------

hwantech.tistory.com

 

์žฌ๊ท€์— ๋Œ€ํ•ด ํ•™์Šต ํ›„ ์‹ค์Šต ์ง„ํ–‰

 

 

[์•Œ๊ณ ๋ฆฌ์ฆ˜] ์žฌ๊ท€ ํ•จ์ˆ˜

๐Ÿ“Œ ์žฌ๊ท€ ๐Ÿ“์žฌ๊ท€์˜ ์ดํ•ด ์žฌ๊ท€ : ์›๋ž˜์˜ ์ž๋ฆฌ๋กœ ๋˜๋Œ์•„๊ฐ€๊ฑฐ๋‚˜ ๋˜๋Œ์•„์˜ด ๐Ÿ”— ์žฌ๊ท€์˜ ์ฝ”๋“œ function recursion () { console.log("This is") console.log("recursion!") recursion() } recursion() ํ•จ์ˆ˜? ์ž๊ธฐ ์ž์‹ ์„ ๋์—†์ด ํ˜ธ์ถœ

hwantech.tistory.com

 

 

๐Ÿ“– ํ•™์Šต ๋ชฉํ‘œ

 

 

 

index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Tree View UI</title>
  <link href="https://fonts.googleapis.com/css2?family=Do+Hyeon&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="test.css">
  <link rel="stylesheet" href="index.css">
</head>

<body>
  <div id="mocha"></div>
  <ul id="root"></ul>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.2.0/chai.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/8.2.0/mocha.min.js"></script>
  <script>
    mocha.setup('bdd');
  </script>
  <script src="./fix_me.js"></script>
  <script src="./test/index.test.js"></script>
  <script>
    mocha.run();
  </script>
</body>

</html>

 

body script ์•ˆ์— <ul id="root"></ul> ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค

์ด ๊ตฌ๋ฌธ ์•„๋ž˜์— ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ ์ž…๋ ฅ

 

 

fix_me.js

// ์—ฌ๋Ÿฌ๋ถ„๋“ค์ด tree-UI๋ฅผ ๋งŒ๋“œ์…”์•ผ ํ•  ๋ฉ”๋‰ดํŒ์ž…๋‹ˆ๋‹ค.
// menu๋Š” ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ , createTreeView ํ•จ์ˆ˜๋งŒ ์ˆ˜์ •ํ•˜์„ธ์š”.

const menu = [
  {
    type: 'group',
    name: '์Œ๋ฃŒ',
    children: [
      {
        type: 'group',
        name: '์ฝœ๋“œ ๋ธŒ๋ฃจ',
        children: [
          { type: 'item', name: '๋‚˜์ดํŠธ๋กœ ์ฝœ๋“œ ๋ธŒ๋ฃจ' },
          { type: 'item', name: '๋Œ์ฒด ์ฝœ๋“œ ๋ธŒ๋ฃจ' },
          { type: 'item', name: '์ œ์ฃผ ๋น„์ž๋ฆผ ์ฝœ๋“œ ๋ธŒ๋ฃจ' },
          { type: 'item', name: '์ฝœ๋“œ ๋ธŒ๋ฃจ' },
        ],
      },
      {
        type: 'group',
        name: 'ํ”„๋ผํ‘ธ์น˜๋…ธ',
        children: [
          { type: 'item', name: '์• ํ”Œ ์ฟ ํ‚ค ํฌ๋ฆผ ํ”„๋ผํ‘ธ์น˜๋…ธ' },
          { type: 'item', name: '๋”๋ธ” ์—์Šคํ”„๋ ˆ์†Œ ์นฉ ํ”„๋ผํ‘ธ์น˜๋…ธ' },
          { type: 'item', name: '๋ชจ์นด ํ”„๋ผํ‘ธ์น˜๋…ธ' },
          { type: 'item', name: 'ํ”ผ์Šคํƒ€์น˜์˜ค ํฌ๋ฆผ ํ”„๋ผํ‘ธ์น˜๋…ธ' },
        ],
      },
      {
        type: 'group',
        name: '๋ธ”๋ Œ๋””๋“œ',
        children: [
          { type: 'item', name: '๋ง๊ณ  ๋ฐ”๋‚˜๋‚˜ ๋ธ”๋ Œ๋””๋“œ' },
          { type: 'item', name: '๋”ธ๊ธฐ ์š”๊ฑฐํŠธ ๋ธ”๋ Œ๋””๋“œ' },
          { type: 'item', name: '์ž๋ชฝ ์…”๋ฒ— ๋ธ”๋ Œ๋””๋“œ' },
          { type: 'item', name: 'ํ”ผ์น˜ & ๋ ˆ๋ชฌ ๋ธ”๋ Œ๋””๋“œ' },
        ],
      },
      {
        type: 'group',
        name: 'ํ‹ฐ',
        children: [
          { type: 'item', name: '๋ผ์ž„ ํŒจ์…˜ ํ‹ฐ' },
          { type: 'item', name: '๋ฏผํŠธ ๋ธ”๋ Œ๋“œ ํ‹ฐ' },
          { type: 'item', name: '์•„์ด์Šค ์œ ์Šค๋ฒ ๋ฆฌ ํ‹ฐ' },
          { type: 'item', name: '์•„์ด์Šค ์บ๋ชจ๋งˆ์ผ ๋ธ”๋ Œ๋“œ ํ‹ฐ' },
        ],
      },
      {
        type: 'group',
        name: '์ฃผ์Šค',
        children: [
          { type: 'item', name: 'ํ•œ๋ฐฉ์— ์ญ‰ ๊ฐ๋‹น' },
          { type: 'item', name: 'ํŒŒ์ดํŒ… ์ฒญ๊ทค' },
          { type: 'item', name: '๋”ธ๊ธฐ์ฃผ์Šค' },
          { type: 'item', name: '๋„์™€์ฃผ ํ‘ํ‘' },
        ],
      },
    ],
  },
  {
    type: 'group',
    name: '์Œ์‹',
    children: [
      {
        type: 'group',
        name: '๋นต',
        children: [
          { type: 'item', name: 'ํŠธ๋Ÿฌํ”Œ ๋ฏธ๋‹ˆ ์Šค์ฝ˜' },
          { type: 'item', name: '๋ณด๋Šฌ๋ฐค ๋ชฝ๋ธ”๋ž‘ ๋ฐ๋‹ˆ์‰ฌ' },
          { type: 'item', name: '๊ณ ์†Œํ•œ ์น˜์ฆˆ ๋ฒ ์ด๊ธ€' },
          { type: 'item', name: '๋ฏธ๋‹ˆ ํด๋ž˜์‹ ์Šค์ฝ˜' },
        ],
      },
      {
        type: 'group',
        name: '์ผ€์ดํฌ',
        children: [
          { type: 'item', name: '๋ฐ€๋‹น ์—๊ทธ ํƒ€๋ฅดํŠธ' },
          { type: 'item', name: '๋งˆ์Šค์นดํฌ๋„ค ํ‹ฐ๋ผ๋ฏธ์ˆ˜ ์ผ€์ดํฌ' },
          { type: 'item', name: '๋ธ”๋ฃจ๋ฒ ๋ฆฌ ์ฟ ํ‚ค ์น˜์ฆˆ ์ผ€์ดํฌ' },
          { type: 'item', name: '๋ถ€๋“œ๋Ÿฌ์šด ์ƒํฌ๋ฆผ ์นด์Šคํ…”๋ผ' },
        ],
      },
      {
        type: 'group',
        name: '์ƒŒ๋“œ์œ„์น˜',
        children: [
          { type: 'item', name: '์• ํ”Œ ๊นŒ๋ง๋ฒ ๋ฅด ์ƒŒ๋“œ์œ„์น˜' },
          { type: 'item', name: 'ํŠธ๋ฆฌํ”Œ ๋จธ์‰ฌ๋ฃธ ์น˜์ฆˆ ์ƒŒ๋“œ์œ„์น˜' },
          { type: 'item', name: '๋กœ์ŠคํŠธ ์น˜ํ‚จ ์ƒ๋Ÿฌ๋“œ ๋ฐ€ ๋ฐ•์Šค' },
          { type: 'item', name: 'B.E.L.T ์ƒŒ๋“œ์œ„์น˜' },
        ],
      },
      {
        type: 'group',
        name: '๊ณผ์ผ',
        children: [
          { type: 'item', name: 'ํ•˜๋ฃจ ํ•œ ์ปต RED' },
          { type: 'item', name: 'ํ•œ๋ผ๋ด‰ ๊ฐ€๋“ ํ•ธ๋”” ์ ค๋ฆฌ' },
        ],
      },
      {
        type: 'group',
        name: '์Šค๋‚ต',
        children: [
          { type: 'item', name: '๋ฆฌ์ €๋ธŒ ์ดˆ์ฝœ๋ฆฟ ์„ธํŠธ' },
          { type: 'item', name: '๋กœ์Šคํ‹ฐ๋“œ ์•„๋ชฌ๋“œ ์•ค ์ดˆ์ฝœ๋ฆฟ' },
          { type: 'item', name: '๋งˆ์นด๋กฑ' },
          { type: 'item', name: '์ž์ผ๋ฆฌํ†จ ์บ”๋”” ํฌ๋ฆฌ์Šคํƒˆ ๋ฏผํŠธ' },
        ],
      },
      {
        type: 'group',
        name: '์•„์ด์Šคํฌ๋ฆผ',
        children: [
          { type: 'item', name: '์ž๋ฐ” ์นฉ ์œ ๊ธฐ๋† ๋ฐ”๋‹๋ผ ์•„์ด์Šคํฌ๋ฆผ' },
          { type: 'item', name: '๋„›์ธ  ์ดˆ์ฝœ๋ฆฟ ์•„ํฌ๊ฐ€ํ† ' },
          { type: 'item', name: '๋ฐ”๋‹๋ผ ์•„ํฌ๊ฐ€ํ† ' },
        ],
      },
    ],
  },
  {
    type: 'group',
    name: '๊ตฟ์ฆˆ',
    children: [
      {
        type: 'group',
        name: '๋จธ๊ทธ',
        children: [
          { type: 'item', name: '์šฐ๋ฆฌ ํ•œ๊ธ€ ๋ธ”๋ž™ ๋จธ๊ทธ 473ml' },
          { type: 'item', name: '์„œ์šธ ํˆฌ์–ด ๋จธ๊ทธ 355ml' },
          { type: 'item', name: '์Šคํƒ€๋ฒ…์Šค 1ํ˜ธ์  ๋จธ๊ทธ 400ml' },
          { type: 'item', name: '์„œ์šธ ์ œ์ฃผ ๋ฐ์ด๋จธ๊ทธ ์„ธํŠธ' },
        ],
      },
      {
        type: 'group',
        name: 'ํ…€๋ธ”๋Ÿฌ',
        children: [
          { type: 'item', name: 'SS ๋ถ€์‚ฐ ํˆฌ์–ด ํ…€๋ธ”๋Ÿฌ 355ml' },
          { type: 'item', name: 'SS ๋ธ”๋ž™ ํ—ค๋ฆฌํ‹ฐ์ง€ ์˜ค๋“œ๋ฆฌ ํ…€๋ธ”๋Ÿฌ 355ml' },
          { type: 'item', name: 'SS ์—์น˜๋“œ ์‹ค๋ฒ„ ํ…€๋ธ”๋Ÿฌ 473ml' },
        ],
      },
      {
        type: 'group',
        name: '์•…์„ธ์‚ฌ๋ฆฌ',
        children: [
          { type: 'item', name: '๋ฆฌ์ €๋ธŒ ์˜ค๋ Œ์ง€ ์นด๋“œ ํ™€๋”' },
          { type: 'item', name: '์Šคํƒ€๋ฒ…์Šค 1ํ˜ธ์  ์—์ฝ”๋ฐฑ' },
          { type: 'item', name: '์Šคํƒ€๋ฒ…์Šค 1ํ˜ธ์  ๋žฉํƒ‘ ํŒŒ์šฐ์น˜' },
        ],
      },
    ],
  },
  {
    type: 'group',
    name: '์นด๋“œ',
    children: [
      { type: 'item', name: '10000์›๊ถŒ' },
      { type: 'item', name: '30000์›๊ถŒ' },
      { type: 'item', name: '50000์›๊ถŒ' },
      { type: 'item', name: '100000์›๊ถŒ' },
    ],
  },
];

// TODO: createTreeView ํ•จ์ˆ˜๋ฅผ ์žฌ๊ท€(์ž๊ธฐ ์ž์‹ ์„ ๊ณ„์† ๋ถ€๋ฅด๊ฒŒ ํ•จ)ํ˜ธ์ถœํ•˜์—ฌ ํ…Œ์ŠคํŠธ์ผ€์ด์Šค๋ฅผ ํ†ต๊ณผํ•˜์„ธ์š”.
// GOAL: ์ตœ์ข… ๊ฒฐ๊ณผ๊ฐ€ resut.html์™€ ๊ฐ™์€ ๋ชจ์Šต์œผ๋กœ ๋‚˜์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค.

const root = document.getElementById('root');
function createTreeView(menu, currentNode) {
  // TODO: createTreeView ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”.
  }

createTreeView(menu, root);

 

 

 menu ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด tree view๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค
    โœ“ ul#root ์—˜๋ฆฌ๋จผํŠธ ์•ˆ์— ์นดํ…Œ๊ณ ๋ฆฌ(์Œ๋ฃŒ, ์Œ์‹, ๊ตฟ์ฆˆ, ์นด๋“œ)๋ฅผ ๋ Œ๋”๋งํ•  4๊ฐœ์˜ li ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

for(let i =0; i < menu.length; i++){
const li = document.createElement('li');
...

}


    โœ“ ์นดํ…Œ๊ณ ๋ฆฌ(์Œ๋ฃŒ, ์Œ์‹, ๊ตฟ์ฆˆ, ์นด๋“œ) ์—˜๋ฆฌ๋จผํŠธ ์•ˆ์—๋Š” ๊ฐ๊ฐ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ๊ฐ์ถฐ์ค„ checkbox๊ฐ€ ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

if(menu[i].children){
	const ipnut = document.createElement('input');
    input.type = 'checkbox';
}


    โœ“ ์Œ๋ฃŒ, ์Œ์‹, ๊ตฟ์ฆˆ, ์นด๋“œ ์นดํ…Œ๊ณ ๋ฆฌ ์ด๋ฆ„(name)์„ span ํƒœ๊ทธ๋กœ ๊ฐ์‹ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค

if(menu[i].children){
...
const span = document.createElement('input');
span.textContext = menu[i].name;
}


    โœ“ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์—†๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ฒฝ์šฐ, li ์—˜๋ฆฌ๋จผํŠธ ์•ˆ์— ๋‹จ์ˆœํžˆ ์ด๋ฆ„(name)๋งŒ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. (checkbox ๋ฐ span, ul์„ ํฌํ•จํ•˜๋ฉด ์•ˆ๋ฉ๋‹ˆ๋‹ค)   

if(menup[i].children){
...
}else{
	// ์ž์‹๋…ธ๋“œ๊ฐ€ ์—†์„ ๋•Œ ์ด๋ฆ„ ํ‘œ๊ธฐ
    li.textContext = menu[i].name;
    currentNode.append(li);
}

    โœ“ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์žˆ๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ฒฝ์šฐ, li ์—˜๋ฆฌ๋จผํŠธ ์•„๋ž˜์— ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋ Œ๋”๋งํ•  ์ƒˆ๋กœ์šด ul์ด ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (1)

    โœ“ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์žˆ๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ฒฝ์šฐ, li ์—˜๋ฆฌ๋จผํŠธ ์•„๋ž˜์— ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋ Œ๋”๋งํ•  ์ƒˆ๋กœ์šด ul์ด ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค (2)

 

// ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์žˆ๋Š” ๋ฐ์ดํ„ฐ์ผ ๊ฒฝ์šฐ
// ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋ Œ๋”๋งํ•  ์ƒˆ๋กœ์šด ul์„ ๋งŒ๋“ ๋‹ค
if(menu[i].children){
...
const ul = document.createElement('ul')
// ์ƒ์„ฑ๋œ ๋ถ€๋ถ„๋“ค์„ li์— ์‚ฝ์ž…
li.append(input,span,ul);
// root์— ๋„ฃ์–ด์ค€๋‹ค
currentNode.append(li);
// ์ด๋•Œ ์žฌ๊ท€ํ•จ์ˆ˜ ํ˜ธ์ถœ -> ์ž์‹๋…ธ๋“œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ
createTreeView(menu[i].children, ul);
}


    โœ“ type ์†์„ฑ์ด item์ธ ๊ฐ์ฒด๋Š” li ํƒœ๊ทธ๋กœ name ์†์„ฑ๊ฐ’์„ ๊ฐ์‹ธ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

 

์œ„์™€ ๋™์ผ

๋ฐ˜์‘ํ˜•