Incorrect count when using element count by tag name

50 Views Asked by At

The code I am using is:

function findOccurrences(string) {
  var elements = document.getElementsByTagName('*');
  var foundCount = 0;

  for (var i = 0, il = elements.length; i < il; i++) {
    if (!elements[i].textContent || !elements[i].textContent.match(string)) {
      continue;
    }
    foundCount++;
  }

  return +foundCount;
}
<strong><strong>text here (</strong></strong>
<span id="anm_tot" class="wysiwyg-font-size-normal">&nbsp;</span>
<strong>) </strong>
<script>
  var countElement = document.getElementById('anm_tot');
  countElement.textContent = findOccurrences('¤');
</script>

In the page itself, I have hidden that character for counting.

(Found as code suggested by another stackoverflow user)

That is the other 'complication' is that all has to work on a ZenDesk Knowledge Base page. As well, I used to be better at this but post a stroke and cancer, there are holes in my knowledge.

It does count but the count is incorrect - it should be the same count as a Command-F (sorry working on a mac) but it returns 12 and the command-F returns 5.

I need an exact count. This is not an optimal solution but the only one that I have been able to get to work even to this point. I have tried other options such as counting LI elements but I need the count to appear as part of the knowledge base page I am editing and I have not been able to get that count to appear on the page itself.

1

There are 1 best solutions below

1
Carsten Massmann On

In order to avoid counting the same text passage more than once you should analyse only the outermost DOM element (=container, in this example: the first <div>) that holds all the other elements on the page. Here is a working snippet:

function findOccurrences(string){
 // wrong method:
 console.log("wrong:",[...document.querySelectorAll("*")]
 .reduce((a,c)=>a+[...c.textContent.matchAll(string)].length,0));
// correct method:
console.log("correct:",[...document.querySelector("div").textContent.matchAll(string)].length);
}
findOccurrences('¤')
<div>¤<div>¤<br><span>¤<b>¤</b>¤</span>
</div></div>

Update:

The script for your actual page could look something like this:

function findOccurrences(string){
 return [...document.querySelector("div").textContent.matchAll(string)].length;
}
document.addEventListener("DOMContentLoaded",()=>document.getElementById("anm_tot").textContent=
findOccurrences('¤'));
<div>¤<div>¤<br><span>¤<b>¤</b>¤</span>
</div></div>

<h2>Number of occurrences:
<span id="anm_tot" class="wysiwyg-font-size-normal">&nbsp;</span> <strong>) </strong></h2>