1

I'm attempting to find a specific string in a document which potentially can have the text split by other tags (i.e. "< p > This is an < span > example < /span > < /p >"), where I would want to find the string "This is an example" in a much larger document and return the first parent element in belongs to (in this case, a < p > tag)

I wrote some code to find a string's index in an arbitrary web document...in such a way that it hopefully accommodates the string being split. It returns the index where the string starts. I'm wondering how to either do this more efficiently OR if this is a decent way, I'm wondering how, given the index of a string in a $("body").html() string, how to retrieve the parent element containing that index.

EDIT: Perhaps this was unclear. I am looking for the parent of a string in a document, and I cannot make any assumptions about where the string may be or what tag its parent may be. So, I call $("body").html() and attempt to find the index of the substring in the html "string". Probably certainly inefficient, I'm really desperate for help.
function get_string_parent(str) { 
    var p = null;
    var split = str.split(' ');
    var body_html = $("body").html();
    var lower_ind = 0;
    var upper_ind = split.length;
    var STOPPING_LENGTH = 3; //give up after not finding string of length 3... 
    var ind = -1;
    do {  //shrink string until a snippet is found
        ind = body_html.indexOf(split.slice(lower_ind, upper_ind).join(' '));
        upper_ind--;
    }
    while (ind < 0 && upper_ind > STOPPING_LENGTH);
    console.log("FOUND AT INDEX: ", ind);
    //console.log("String around index: ", body_html.slice(ind - 10, ind + 10));
    //I"M UNSURE OF, GIVEN A VALID "IND", how to get the parent element at that index

    return p;

Thanks for your time, I'm not familiar with webdev and I'm almost certainly in over my head.

Community
  • 1
  • 1
Aaron Parisi
  • 13
  • 1
  • 4
  • Your attempt to *`"find a specific string in a document which potentially can have the text split by other tags"`* is a bit unclear... Also have you tried to use DOMParser? – Roko C. Buljan May 30 '18 at 05:54
  • `parent element of string` ... a string does not have a parent element ... in fact, a string in javascript is not at all related to the DOM – Jaromanda X May 30 '18 at 05:57
  • by "parent element of a string" I mean 'the element containing a string', my vocabulary might not be on-point – Aaron Parisi May 30 '18 at 06:04
  • @RokoC.Buljan "_split by other tags_" means that the string OP wants to find possibly contains (inline) elements. – Teemu May 30 '18 at 06:25

3 Answers3

1

This will get you started. You can use :contains() selector for finding string in html.

function getStringParent(str) { 
  return $("p:contains('"+ str +"')");
}
var parent = getStringParent('This is an  example');
console.log('found ' + parent.length + ' items' + '\n');
console.log(parent);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p> This is an <span> example </span> </p>
rrk
  • 15,677
  • 4
  • 29
  • 45
0

Use padolsey's findAndReplaceDOMText tool and pass it the replace option so that it returns the node you're looking for.

Alex Steinberg
  • 1,426
  • 13
  • 25
  • I really like this suggestion because I was already using findAndReplaceDOMText for a separate part of the project! – Aaron Parisi May 31 '18 at 23:36
-1

You need recursion for this:

function recursivelySearchString(str,from){
    if(from.textContent.indexOf(str)==-1)
        return null // doesn't contain the string, stop

    var children = Array.from(from.children)
    if(children.length>0){
        // current element has children, look deeper
        for(var i=0;i<children.length;i++){
            var found = recursivelySearchString(str, children[i])
            if(found)
                return found
        }
    }

    // none of the children matched, return the parent
    return from
}

Calling recursivelySearchString('foobar',document.body) will return the closest element containing the phrase. Note it will return the element wrapped in a jQuery selector. If nothing is found it returns null.

Example:

function recursivelySearchString(str,from){
    if(from.textContent.indexOf(str)==-1)
        return null // doesn't contain the string, stop

    var children = Array.from(from.children)
    if(children.length>0){
        // current element has children, look deeper
        for(var i=0;i<children.length;i++){
            var found = recursivelySearchString(str, children[i])
            if(found)
                return found
        }
    }

    // none of the children matched, return the parent
    return from
}

var found = recursivelySearchString('dolores',document.body)
found.style.backgroundColor = 'yellow'
<div>
  <p>
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
  </p>
  <p>
    At vero eos et accusam et <span>justo duo dolores et ea rebum.</span>
    Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
  </p>
</div>
Manuel Otto
  • 6,410
  • 1
  • 18
  • 25