Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I find all text nodes between two element nodes with JavaScript/jQuery?

Given the following HTML-Fragment:

<div>
  <p>
    abc <span id="x">[</span> def <br /> ghi
  </p>
  <p>
    <strong> jkl <span id="y">]</span> mno </strong>
  </p>
</div>

I need an algorithm to fetch all nodes of type Text between #x and #y with Javascript. Or is there a JQuery function that does exactly that?

The resulting Text nodes (whitespace nodes ignored) for the example above would then be:

['def', 'ghi', 'jkl']
like image 913
Martin Andert Avatar asked Dec 09 '10 13:12

Martin Andert


People also ask

How to select text node jQuery?

The textNodes of any element can be selected using jQuery by selecting all the nodes and using the filter() method to check the nodeType property. The required element is first selected using the jQuery selector. The contents() method is used on selected elements.

What is nodeType in Javascript?

nodeType. The read-only nodeType property of a Node interface is an integer that identifies what the node is. It distinguishes different kind of nodes from each other, such as elements , text and comments .

How can we check equality of 2 nodes in JS?

isEqualNode() The isEqualNode() method of the Node interface tests whether two nodes are equal. Two nodes are equal when they have the same type, defining characteristics (for elements, this would be their ID, number of children, and so forth), its attributes match, and so on.

What is a text node?

A text node encapsulates XML character content. A text node can have zero or one parent. The content of a text node can be empty. However, unless the parent of a text node is empty, the content of the text node cannot be an empty string.


1 Answers

The following works in all major browsers using DOM methods and no library. It also ignores whitespace text nodes as mentioned in the question.

Obligatory jsfiddle: http://jsfiddle.net/timdown/a2Fm6/

function getTextNodesBetween(rootNode, startNode, endNode) {
    var pastStartNode = false, reachedEndNode = false, textNodes = [];

    function getTextNodes(node) {
        if (node == startNode) {
            pastStartNode = true;
        } else if (node == endNode) {
            reachedEndNode = true;
        } else if (node.nodeType == 3) {
            if (pastStartNode && !reachedEndNode && !/^\s*$/.test(node.nodeValue)) {
                textNodes.push(node);
            }
        } else {
            for (var i = 0, len = node.childNodes.length; !reachedEndNode && i < len; ++i) {
                getTextNodes(node.childNodes[i]);
            }
        }
    }

    getTextNodes(rootNode);
    return textNodes;
}

var x = document.getElementById("x"),
    y = document.getElementById("y");

var textNodes = getTextNodesBetween(document.body, x, y);
console.log(textNodes);
like image 146
Tim Down Avatar answered Oct 12 '22 23:10

Tim Down