0

I want to generate an array of nodes in a page, which will have all of the possible startContainers for Ranges.

I've tried to use a treeWalker but it gives me a node which is deeper than the actual startContainer node, for example:

<p>For those keeping count at home, by the way, the <a target="_blank" href="http://msdn.microsoft.com/en-US/windows/apps/br229516.aspx">Windows 8 Developer Preview site</a> still happily talks about "Metro style app development,"; even though <a target="_blank" href="http://www.istartedsomething.com/20120816/microsofts-new-rule-no-metro-named-apps/">rumor has it</a> that Microsoft is now banning all apps with the word "Metro" in their name from the Windows Store.</p>

(Taken from techcrunch.com)

So my tree walker returns the following:

['For those keeping count at home, by the way, the ','Windows 8 Developer Preview site',' still happily talks about "Metro style app development,"; even though ','rumor has it',' that Microsoft is now banning all apps with the word "Metro" in their name from the Windows Store.']

(Split)

But when I try and get the following: window.getSelection().getRangeAt(0).startContainer.textContent I get:

['For those keeping count at home, by the way, the Windows 8 Developer Preview site still happily talks about "Metro style app development,"; even though rumor has it that Microsoft is now banning all apps with the word "Metro" in their name from the Windows Store.']

(Not split)

Why isn't the startContainer more deep (split)? like the treeWalker is?

Here is the code of the tree walker:

var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ALL, function(node) {
    if (node.nodeType == 3) {
        return NodeFilter.FILTER_ACCEPT;
    } else if (node.offsetWidth && node.offsetHeight) {
        return NodeFilter.FILTER_SKIP;
    } else {
        return NodeFilter.FILTER_REJECT;
    }
}, false);
funerr
  • 7,212
  • 14
  • 81
  • 129

1 Answers1

2

I imagine you've selected the whole of an element, such as one of the links. The crucial fact is that the startContainer of a range obtained from the selection is not guaranteed to be a text node.

If a whole element is selected, some browsers will report the selection as spanning the children of the element's parent node. For a selection spanning one of a number of consecutive images, for example, it's essential. Imagine the selection encompasses just the second image in the HTML below:

<div><img src="1.jpg"><img src="2.jpg"><img src="3.jpg"></div>

In this case the selected range will have startContainer and endContainer properties that refer to the <div> element and startOffset 1 and endOffset 2, representing the range stretching between the children at indexes 1 and 2 in the container's childNodes property.

Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • I've tried to select: "Windows Store.", why doesn't it return (for the startContainer.textContent): " that Microsoft is now banning all apps with the word "Metro" in their name from the Windows Store." ? – funerr Oct 02 '12 at 13:26
  • That sounds bizarre and wrong. I don't see that in this example: http://jsfiddle.net/DuFhf/ – Tim Down Oct 02 '12 at 13:36
  • Sorry, my bad, I had cloned the range and changed the DOM - that is what made the cloned range go bizarre, thanks for the extra info on ranges! – funerr Oct 02 '12 at 13:50