Troy Wray
Troy Wray

Reputation: 1028

Find an element in a DOM given the exact html of the element

I needed an efficient way to search for a 13 digit numeric code (call it ncode) appearing in an arbitrary way in a html page e.g. it might be <p>ncode</p> or it could be <input type="hidden" value="ncode"> or <span content="ncode"></span>.

I created a regex that finds the html fragment I need and in a specific case it returns

 <span itemprop="gtin13" content="0885913103914"></span>

Having done that, I thought it would be easy to use jQuery to find the actual DOM element but I can't seem to find anything that works. I tried $(body).filter(":contains()") and various similar things.

So the question is, what is the best way to located the element in the DOM whose html matches a known string?

If it can't be done, I guess I'll have to parse the found html string for different properties and then select elements using those properties. It just seems there should be a way of directly selecting the element so I can query and manipulate it in the DOM.

Upvotes: 1

Views: 693

Answers (2)

Reinstate Monica Cellio
Reinstate Monica Cellio

Reputation: 26143

You can do what you're asking but I'd recommend not doing it, purely for performance reasons. If you take every element in the document body and parse them with some defined logic (dependent on how you want to identify the particular elements) then you can get a collection of just the matching elements.

This example shows finding the elements with the specific value anywhere in the element...

// this returns the element(s) that contain the given text
var elements = $("body span").filter(function() {
	return this.outerHTML.match("0885913103914");
}).toArray();

elements.forEach(function(el) { console.log(el.innerText); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span itemprop="gtin13" content="0885913103914">Span with correct content attribute.</span><br />
<span itemprop="gtin13" content="0885913103915">Span with incorrect content attribute.</span><br />
<span itemprop="gtin13" content="0885913103914">Span with correct content attribute.</span><br />
<span itemprop="gtin13" content="0885913103915">Span with 0885913103914 inside the contents.</span><br />

You would need to adjust the filter function to suit other criteria. Basically, if you return true then the element is included in the output.

If you can do this effectively with your original regex solution then I'd recommend that instead.

Upvotes: 0

gurvinder372
gurvinder372

Reputation: 68433

Try this simple approach

  • Find the name of the node which represent the html-to-find
  • Find the classes of the node which represent the html-to-find
  • Prepare a selector with the above two information and execute the same.

Demo

var htmlToFind = '<span class="clas31" attribute1="4">fdgdfg</span>';

var nodeName = $( htmlToFind )[0].nodeName;
var classList = [].slice.call($( htmlToFind )[0].classList).join(".");

var isFound = $( nodeName + "." + classList ).length > 0

console.log( isFound );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <span class="class1" attribute1="2">345345</span>
  <span class="class2" attribute1="2"><a>a34rrt5345</a></span>
  <span class="clas31" attribute1="4">fdgdfg</span>
  <div asd="sd">rdfgdfg</div>
</div>

You can optimize this further by checking the other attributes of html-to-find as well.

If the number of nodes returned by nodename and classes are more than 1, then filter them further as

var htmlToFind = '<span class="clas31" attribute1="4">fdgdfg</span>';

var nodeName = $( htmlToFind )[0].nodeName;
var classList = [].slice.call($( htmlToFind )[0].classList).join(".");

var length = $( nodeName + "." + classList ).length

console.log( "total matches by classnames and node name " + length );
var exactMatches = [];
$( nodeName + "." + classList ).each( function(){
   if ( this.outerHTML == htmlToFind )
   {
      exactMatches.push( this )
   }
});
console.log( "exactMatches" , exactMatches  )
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <span class="class1" attribute1="2">345345</span>
  <span class="class2" attribute1="2"><a>a34rrt5345</a></span>
  <span class="clas31" attribute1="4">fdgdfg</span>
  <span class="clas31" attribute1="4">fdg2dfg</span>
  <div asd="sd">rdfgdfg</div>
</div>

Upvotes: 2

Related Questions