3

I need some help write the logic for finding the number of descendants of an element.

html :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <main>
        <ul>
          <li><button>item</button></li>
        </ul>
        <p>Hello, world</p>
      </main>
      <script src="index.js"></script>
</body>
</html>

index.js :

  function countDescendants(element) {}

  // Test code
  const result = countDescendants(document.querySelector("main"));
  if (result !== 4) {
    console.error(`fail: ${result}`);
  } else {
    console.log("Pass!");
  }

Can some help me to write the countDescendants function.We cant use built in function. should write our own logic. For this particular example it should return the result 4.

4 Answers4

2

If you want all the children and descentants, the simplest way to do this is to use querySelectorAll this way:

document.querySelectorAll('main *').length

Complete code:

  // Test code
  const result = document.querySelectorAll("main *").length;
  if (result !== 4) {
    console.log(`fail: ${result}`);
  } else {
    console.log("Pass!");
  } 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <main>
        <ul>
          <li><button>item</button></li>
        </ul>
        <p>Hello, world</p>
      </main>
      <script src="index.js"></script>
</body>
</html>
Mr Khan
  • 2,139
  • 1
  • 7
  • 22
  • How to get unique selector for an element: https://stackoverflow.com/a/66291608/4592648 Edit: you don't have to, just call querySelectorAll('*') on the node itself – Monday Fatigue Nov 09 '21 at 12:39
0

The following code uses the .children property of each element and recursively walks the DOM tree, counting children as it goes.

function countDescendants(el) {
  function countChildren({ children }) {
    let count = 0
    if(!children.length) return 0
    for(let el of [...children]) {
      count++
      count += countChildren(el)
    }
    return count
  }
  return countChildren(el)
}
const result = countDescendants(document.querySelector('main'))
console.log(result) // 4
<main>
  <ul>
    <li><button>item</button></li>
  </ul>
  <p>Hello, world</p>
</main>
Ben Aston
  • 53,718
  • 65
  • 205
  • 331
0

Use Element.querySelectorAll()

The Element method querySelectorAll() returns a static (not live) NodeList representing a list of elements matching the specified group of selectors which are descendants of the element on which the method was called.

function countDescendants(el) {
  return el.querySelectorAll('*').length
}
Monday Fatigue
  • 223
  • 1
  • 3
  • 19
0

//=======================================================
// If you want to count children of an element

document.querySelector('#total-children').innerText = document.querySelectorAll('#parent > *').length + ' Children';

// or

document.querySelector('#total-children-2').innerText = document.querySelector('#parent').childElementCount + ' Children';

// In you have already selected an element and wants to find his children then you can do this

const elem = document.querySelector('#parent');
document.querySelector('#total-children-3').innerText = elem.querySelectorAll(':scope > *').length + ' Children';

//=======================================================


// If you want to count descendants
document.querySelector('#total-descendants-2').innerText = document.querySelectorAll('#parent *').length + ' Descendants';
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Sample</title>
</head>
<body>
  <div id="parent">
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ul>
    <h5>Heading</h5>
    <h6>Heading</h6>
  </div>
  <p id="total-children"></p>
  <p id="total-children-2"></p>
  <p id="total-children-3"></p>
  <p id="total-descendants-2"></p>
</body>
</html>