title: Generate the css selector for the clicked element in a single page application
body: <p>so as stated in the the title, I want to get the css selector of any element that's been clicked on. I can handle 95% of the cases so far but I'm currently facing a problem that maybe doesn't have a solution: buttons that trigger page changes in single page application.
  The DOM changes before the selector is finished.</p>
  <p>As you can see, I'm using the path property of the event object to generate the selector. I'd imagine building the selector only from the event target itself will face the same problem.</p>
  <p>I can still build a more or less valid selector for the element, as I don't lose the info of the path property of the event. But since the references to the parent- and childNodes are lost I'm losing the info about the index of the current Element being processed. Is there a way to avoid that?</p>
  <pre><code>document.onclick = (event) =&gt;
  {
      // only use relevant parts of path
      let cssSelector = event.path.reverse().slice(4).reduce((searchString, currElem) =&gt;
      {
          if (searchString)
          {
              searchString += '&gt;';
          }
          if (currElem.id)
          {
              return `#${currElem.id}`;
          }
          return `${searchString}${elemToQueryString(currElem)}`;
      }, '');
      cssSelector = cssSelector.slice(-1) === '&gt;' ? cssSelector.slice(0, -1) : cssSelector;
  };
  
  function elemToQueryString(elem)
  {
      let queryString = elem.tagName.toLowerCase();
      if (elem.className.length)
      {
          queryString += `.${elem.className.replaceAll(' ', '.').replaceAll(':', '\\:')}`;
      }
      return queryString + elemToNthChild(elem);
  }
  
  function elemToNthChild(elem)
  {
      if (elem.parentNode.children.length === 1)
      {
          return '';
      }
      const index = Array.prototype.indexOf.call(elem.parentNode.children, elem);
      return index === -1 ? '' : `:nth-child(${index + 1})`;
  }
  </code></pre>