Open In App

How to create a function `generateSelector` to generate CSS selector path of a DOM element ?

In this article, we will learn about CSS selectors, and we will also implement a `generateSelector()` function that returns a string value to provide a valid selector to a target DOM element.

What is a CSS Selector?



A CSS selector is used to select a group of elements (or nodes in the DOM tree) that follow a certain pattern. 

Example: Here is an example of CSS selectors.






<!DOCTYPE html>
<html>
<head>
    <title>Page Title</title>
 
    <style>
        /* h2 selector selects all the h2
        elements present in body */
        h2 {
            background-color: red;
        }
 
        /* div > h3 selector selects all the
        h3 elements which are direct
        descendants of div */
        div>h3 {
            background-color: blue;
        }
    </style>
</head>
 
<body>
    <h2>Welcome To GFG</h2>
    <div>
        <h3>Hello World!</h3>
    </div>
</body>
</html>

Output:

Code output

Understanding the outline concept behind generateSelector() Function: Now, let’s talk about how to create a `generateSelector()` function which returns a valid selector string to a target DOM element that presents inside a DOM tree. For a better understanding, let’s take a look at some of the examples of the function and its expected response. 

Example: Here is the implementation of the above-explained method.




<!DOCTYPE html>
<html>
<head>
    <title>Page Title</title>
</head>
 
<body>
    <h2>Welcome To GFG</h2>
    <div>
        <h3>Hello World!</h3>
        <div>
            <p>Some random text</p>
        </div>
    </div>
 
    <script>
        let target = document.querySelector('h3');
        generateSelector(target);
 
        // Expected output -
        //"HTML > BODY:nth-child(2) > DIV:nth-child(3) > H3"
 
        target = document.querySelector('h2');
        generateSelector(target);
        // "HTML > BODY:nth-child(2) > H2:nth-child(2)"
 
        target = document.querySelector('p');
        generateSelector(target);
          // "HTML > BODY:nth-child(2) > DIV:nth-child(3)
          // > DIV:nth-child(2) > P"
    </script>
</body>
</html>

The above code is just a pseudo code that does not have the implementation of the generateSelector function. It is only there to help you understand what the function is for. We are going to implement this function down below in the next section – 

Expected Output:

HTML > BODY:nth-child(2) > DIV:nth-child(3) > H3
HTML > BODY:nth-child(2) > H2:nth-child(2)
HTML > BODY:nth-child(2) > DIV:nth-child(3) > DIV:nth-child(2) > P

Example: Implementing `generateSelector()` function: Now, we have a good grasp on what the `generateSelector` function is, let’s try to implement it –




<!DOCTYPE html>
<html>
<head>
    <title>Page Title</title>
</head>
<body>
    <h2>Welcome To GFG</h2>
    <div>
        <h3>Hello World!</h3>
        <div>
            <p>Some random text</p>
        </div>
    </div>
 
    <script>
        // Let's write a generateSelector() function
        // that should return selector path to h3
        // inside the div
        const generateSelector = (target) => {
            const selectorPath = [];
 
            while (target.tagName) {
                let i = 0;
 
                if (target.parentNode) {
                    const children = target.parentNode.children;
 
                    while (i < children.length && children[i] !== target) {
                        i++;
                    }
                }
 
                selectorPath.unshift(target.nodeName + (
                    i > 0 ? `:nth-child(${i + 1})` : ''));
                target = target.parentNode;
            }
 
            return selectorPath.join(' > ');
        }
 
        let target = document.querySelector('h3');
        console.log(generateSelector(target));
        // Expected output -
        // "HTML > BODY:nth-child(2) > DIV:nth-child(3) > H3"
 
        target = document.querySelector('h2');
        console.log(generateSelector(target));
        // "HTML > BODY:nth-child(2) > H2:nth-child(2)"
 
        target = document.querySelector('p');
        console.log(generateSelector(target));
      // "HTML > BODY:nth-child(2) > DIV:nth-child(3)
      // > DIV:nth-child(2) > P"
    </script>
</body>
</html>

Let’s break the above code step by step – 

Output:

Code output

Example 2: In this example, we are implemented in the same way as Example 1, but it has different child elements in the body tag, so the different outputs get logged to the console.




<!DOCTYPE html>
<html>
<head>
    <title>Page Title</title>
</head>
 
<body>
    <h1>Welcome to GFG</h1>
    <div>
        <h2>Random text</h2>
        <button>Click me</button>
        <p>Hello world</p>
    </div>
 
    <script>
        // Let's write a generateSelector() function
        // that should return selector path to h3
        // inside the div
        const generateSelector = (target) => {
            const selectorPath = [];
 
            while (target.tagName) {
                let i = 0;
 
                if (target.parentNode) {
                    const children = target.parentNode.children;
 
                    while (i < children.length && children[i] !== target) {
                        i++;
                    }
                }
 
                selectorPath.unshift(target.nodeName +
                    (i > 0 ? `:nth-child(${i + 1})` : ''));
                target = target.parentNode;
            }
 
            return selectorPath.join(' > ');
        }
 
        let target = document.querySelector('h1');
        console.log(generateSelector(target));
 
        target = document.querySelector('h2');
        console.log(generateSelector(target));
 
        target = document.querySelector('button');
        console.log(generateSelector(target));
 
        target = document.querySelector('p');
        console.log(generateSelector(target));
    </script>
</body>
</html>

 Output:

 


Article Tags :