views:

1180

answers:

3

I can use the getElementsByTagName() function to get a collection of elements from an element in a web page.

I would like to be able to use a similar function on the contents of a javascript string variable instead of the contents of a DOM element.

How do I do this?

EDIT

I can do this by creating an element on the fly.

var myElement = new Element('div');
myElement.innerHTML = "<strong>hello</strong><em>there</em><strong>hot stuff</strong>";
var emCollection = myElement.getElementsByTagName('em');
alert(emCollection.length); // This gives 1

But creating an element on the fly for the convenience of using the getElementsByTagName() function just doesn't seem right and doesn't work with elements in Internet Explorer.

A: 

HTML in a string is nothing special. It's just text in a string. It needs to be parsed into a tree for it to be useful. This is why you need to create an element, then call getElementsByTagName on it, as you show in your example.

strager
+1  A: 
function countTags(html, tagName) {
    var matches = html.match(new RegExp("<" + tagName + "[\\s>]", "ig"));
    return matches ? matches.length : 0;
}

alert(
    countTags(
        "<strong>hello</strong><em>there</em><strong>hot stuff</strong>",
        "em"
    )
); // 1
nickf
+1  A: 

Injecting the string into DOM, as you have shown, is the easiest, most reliable way to do this. If you operate on a string, you will have to take into account all the possible escaping scenarios that would make something that looks like a tag not actually be a tag.

For example, you could have

<button value="<em>"/>
<button value="</em>"/>

in your markup - if you treat it as a string, you may think you have an <em> tag in there, but in actuality, you only have two button tags.

By injecting into DOM via innerHTML you are taking advantage of the browser's built-in HTML parser, which is pretty darn fast. Doing the same via regular expression would be a pain, and browsers don't generally provide DOM like functionality for finding elements within strings.

One other thing you could try would be parsing the string as XML, but I suspect this would be more troublesome and slower than the DOM injection method.

levik