Is there any way of getting some sort of XPATH for each word which matches a given regular expression? I mean the words displayed by the navigator to the user. That way I could manipulate the HTML corresponding to each word individually.
            Asked
            
        
        
            Active
            
        
            Viewed 195 times
        
    2
            
            
        - 
                    1The easiest solution I can think of would be using jQuery's [`:contains()`](https://api.jquery.com/contains-selector/) selector. Of course, that's only if you're using jQuery. – Hatchet Feb 03 '16 at 16:30
 - 
                    1Visible as opposed to what? What do you mean by "DOM path"? Do you mean an XPath-type expression? What are you planning to do with it? By the way, pieces of text, such as a word, are not addressable by any means, whether it be a XPath or a CSS selector. Both address only **elements**. – Feb 03 '16 at 16:33
 - 
                    @torazaburo yes, I mean that. What if I parse the words, and convert them to elements? Would that be too time-consuming? – mochomecha Feb 03 '16 at 16:43
 - 
                    Turning words and phrases into their own HTMl elements is a different problem; there are quite a few questions here on SO about that, which I am sure you would find if you searched. – Feb 03 '16 at 16:50
 
2 Answers
1
            
            
        There's not a unique XPath to a node, but here's a solution that uses the function cssPath from this answer to return the CSS path of an element that contains text matching a regex.
var cssPath = function(el) {
  if (!(el instanceof Element))
    return;
  var path = [];
  while (el.nodeType === Node.ELEMENT_NODE) {
    var selector = el.nodeName.toLowerCase();
    if (el.id) {
      selector += '#' + el.id;
      path.unshift(selector);
      break;
    } else {
      var sib = el,
        nth = 1;
      while (sib = sib.previousElementSibling) {
        if (sib.nodeName.toLowerCase() == selector)
          nth++;
      }
      if (nth != 1)
        selector += ":nth-of-type(" + nth + ")";
    }
    path.unshift(selector);
    el = el.parentNode;
  }
  return path.join(" > ");
}
var startElem = document.body;
var items = startElem.getElementsByTagName("*");
for (var i = items.length; i--;) {
  var match = items[i].innerHTML.match(/fox/);
  if (match) {
    var matched = document.createElement('div');
    matched.innerHTML = cssPath(items[i]);
    document.getElementById("matches").appendChild(matched);
  }
}
<div>The quick brown fox</div>
<div>jumped over the lazy dog.</div>
<div>The slow orange ocelot</div>
<div>crawled under the quick fox.</div>
<hr>
<h4>Matches /fox/</h4>
<div id="matches"></div>
0
            My solution: In the DOM, I put each word in a newly created span element.
<span id="foundword1">
word1
</span>
<span id="foundword2">
word2
</span>
        mochomecha
        
- 162
 - 1
 - 11