2

Let's say we have a nested span:

<span><span></span></span>

And we want to know whether or not text exists

<span> here <span> </span></span>

or

<span><span></span> here</span>

Let's say we have reference to the parent element node.

Please note that

<span> text <span> text </span> text </span>

or

<span> text <span> text </span></span>

are two entirely possible cases.

CaffeinateOften
  • 571
  • 1
  • 6
  • 19

3 Answers3

1

Shouldn't be much harder than

node.firstChild && node.firstChild.nodeType === Node.TEXT_NODE || 
  node.lastChild && node.lastChild.nodeType === Node.TEXT_NODE

For readability, it is better to use the Node.*_NODE symbolic constants (although they might not be defined in older browsers).

To avoid problems with empty text nodes you might precede this with a

node.normalize()

which

Puts the specified node and all of its subtree into a "normalized" form. In a normalized subtree, no text nodes in the subtree are empty and there are no adjacent text nodes.

See https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize.

To omit comment nodes and whitespace-only text nodes:

var children = Array.prototype.filter.call(node.childNodes || [], function(node) {
  return node.nodeType !== Node.COMMENT_NODE &&
    (node.nodeType !== Node.TEXT_NODE || /\S/.test(node.nodeValue));
}),
    firstChild = children[0],
    lastChild = children[children.length-1];

return firstChild && firstChild.nodeType === Node.TEXT_NODE ||
  lastChild && lastChild.nodeType === Node.TEXT_NODE;

If for some reason it's important to check that there is a child element lurking inside then it would suffice to add a check for

!!node.children.length
  • Accepting this as the answer because it answered my question literally as asked, and provided a lot of helpful/supplemental information – CaffeinateOften Aug 22 '14 at 16:38
0

So using some concepts from @weeklyTea's answer, I've put together three functions that provide answers to the question(s) asked.

I think the important thing to point out, is that we always have one nested element node. And we 'weren't sure' whether or not we have text nodes on either side of the element node. When its put like that, I think these functions will be fairly straight forward:

function isNestedHighlightAtEnd(parent) {
    var childNodes = parent.childNodes;
    var childNodesLength = childNodes.length;

    if( childNodes[childNodesLength-1].nodeType != 3 ) {
        return true;
    }
    else {
        return false;
    }
}

function isNestedHighlightAtMiddle(parent) {

    if( !isNestedHighlightAtBeg( parent ) && !isNestedHighlightAtEnd( parent )) {
        return true;
    }
    else {
        return false;
    }                
}

function isNestedHighlightAtBeg(parent) {
    var childNodes = parent.childNodes;
    var childNodesLength = childNodes.length;

    if( childNodes[0].nodeType != 3) {
        return true;
    }
    else {
        return false;
    } 
}
CaffeinateOften
  • 571
  • 1
  • 6
  • 19
  • Just curious why you would say `if (a != b) { return true; } else { return false; }` instead of `return a != b;`. –  Aug 21 '14 at 19:08
  • 1
    That is a trivial matter, both would work the same way, neither is more efficient than the other. – CaffeinateOften Aug 21 '14 at 19:28
  • Sure, but efficiency aside, it's more verbose, more lines, more surface area for typos and bugs, and unnecessary. –  Aug 21 '14 at 19:39
  • It has been 2 years since I've read this comment, and I still cringe at my silliness. – CaffeinateOften May 02 '16 at 15:27
-1

Not sure that it is best way, but it is my solution first come in to my head:

HTML:

<span id="span1">
    thththt
    <span id="span2"></span>
</span>

JS:

var span = document.getElementById('span1');
var spanChilds = span.childNodes;
var textIndex = -1;

for(var i = 0; i < spanChilds.length; ++i){
    debugger;
    if(spanChilds[i].nodeType == 3){
        textIndex = i;
        break;
    }
}

var nestSpan = document.getElementById('span2');
var nestSpanIndex = Array.prototype.indexOf.call(span.childNodes, nestSpan);

if(nestSpanIndex > textIndex){
    alert('text first')
}else{
    alert('span first')
}

Example on jsFiddle

weeklyTea
  • 316
  • 2
  • 10
  • Would you be able to grab the text instead of hard-coding it in the beginning? We do not know what the text is, and you use this to find your text's index – CaffeinateOften Aug 21 '14 at 11:09
  • See update. We can grab text node by `nodeType` which equals 3. – weeklyTea Aug 21 '14 at 11:22
  • It might be nice to have a solution which does not depend on the ID of a specific element. Also, this solution does not deal with the situation where the text node is the last child node. –  Aug 21 '14 at 19:45