Stack Overflow Q16359314 (2)

Provides $.fn.indexOfTagIncludingHTML(tag).

by acheong87

HTML

<div id="example1">Hello, <b>Andrew</b>. What would you &amp; your friend like to <strike>do</strike> eat?</pdivre>
<div id="example2">Hello, <b>Andrew</b>. <i>What would you &amp; your friend like to <strike>do</strike> eat?</i></div>
<div id="example3">Hello, <b>Andrew</b>. What would <i>you &amp; your friend</i> like to <strike>do</strike> eat?</div>
<pre>0   4   8   12  16  20  24  28  32  36  40  44  48  52  56  60  64  68  72  76  80
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
Hello, &lt;b>Andrew&lt;/b>. What would you &amp; your friend like to &lt;strike>do&lt;/strike> eat?
Hello, &lt;b>Andrew&lt;/b>. &lt;i>What would you &amp; your friend like to &lt;strike>do&lt;/strike> eat?
Hello, &lt;b>Andrew&lt;/b>. What would &lt;i>you &amp; your friend&lt;/i> like to &lt;strike>do&lt;/strike> eat?&lt;/i></pre>
<pre id="output"></pre>

JavaScript

$.fn.lengthOfStartTag = function () {
    var node = this[0];
    if (!node || node.nodeType != 1) {
        $.error("Called $.fn.lengthOfStartTag on non-element node.");
    }
    if (!$(node).is(":empty")) {
        return node.outerHTML.indexOf(node.innerHTML);
    }
    return node.outerHTML.length;
}

$.fn.lengthOfEndTag = function () {
    var node = this[0];
    if (!node || node.nodeType != 1) {
        $.error("Called $.fn.lengthOfEndTag on non-element node.");
    }
    if (!$(node).is(":empty")) {
        var indexOfInnerHTML = node.outerHTML.indexOf(node.innerHTML);
        return node.outerHTML.length - (indexOfInnerHTML + node.innerHTML.length);
    }
    return -1;
}

$.fn.indexOfTagIncludingHTML = function (tag) {
    var nodes = this[0].childNodes;
    var chars = 0;
    for (var i = 0; nodes && i < nodes.length; i++) {
        var node = nodes[i];
        var type = node.nodeType;
        if (type == 3 || type == 4 || type == 5) {
            chars += node.nodeValue.length;
        } else if (type == 1) {
            if (node.tagName == tag.toUpperCase()) {
                return chars;
            } else {
                chars += $(node).lengthOfStartTag();
                var subIndexOfTag = $(node).indexOfTagIncludingHTML(tag);
                if (subIndexOfTag <= 0) {
                    chars += -1 * subIndexOfTag;
                    chars += $(node).lengthOfEndTag();
                } else {
                    chars += subIndexOfTag;
                    return chars;
                }
            }
        }
    }
    // A zero or negative return means "not found," but this variant also indicates
    // how many characters were traversed in the search.
    return -1 * chars;
}

$(document).ready(function () {
    $('#output').append('Example 1, indexOfTagIncludingHTML: ' + $('#example1').indexOfTagIncludingHTML('strike') + '\n');
    $('#output').append('Example 2, indexOfTagIncludingHTML: ' +...