Reputation: 2300
For example, if I have the HTML:
<div id="foo">
<p>Some text in a paragraph</p>
<p>More text in a paragraph</p>
</div>
And someone selects from the start of "in" (paragraph 1) to the end of "More" (paragraph 2), I want to get the selection info like:
{
"object": [div #foo], /* commonAncestorContainer DOM element of the selection */
"source": "<div id="foo">\n<p>Some text in a paragraph</p>\n<p>More text in a paragraph</p>\n</div>", /* outerHTML of the commonAncestorContainer */
"startOffset": 28, /* offset of selection starting point in the source code */
"endOffset": 54 /* offset of selection ending point in the source code */
}
Here are some problems when I attempt to do this:
We can use Range.commonAncestorContainer
to get commonAncestorContainer of a range. However how do we get the real commonAncestorContainer if a selection contains multiple ranges?
How to get the startOffset and endOffset of the selection range in the source code fragment?
Upvotes: 3
Views: 654
Reputation: 714
You may want to check out a related question on finding common ancestors in stack overflow. When the selection contains multiple ranges, you could use the common ancestor algo to the get the common ancestor of all the range.commonAncestorContainer.
Here is a demo of the code to get the start and end offset within the source. You may want to test and extend it as needed.
function getPosition(node, child, childOffset) {
if (!node.contains(child)) {
return -1;
}
var children = node.childNodes;
var pos = 0;
for (var i = 0; i< children.length; i++) {
if (children[i] === child) {
pos += childOffset;
break;
} else if (children[i].contains(child)) {
pos += getPosition(children[i], child, childOffset);
break;
} else if (children[i].nodeName === "#text") {
pos += children[i].textContent.length;
} else {
pos += children[i].outerHTML.length;
}
}
if (node.nodeName !== "#text") {
pos += node.outerHTML.lastIndexOf(node.innerHTML);
}
return pos;
}
Upvotes: 3
Reputation: 4798
Try this function returning an object of information you need
function getInfo(selector)
{
var element = $(selector);
var html = element.clone().wrap('<p>').parent().html();
var Result = new Object();
Result.object = "[" + element.prop("tagName") + " " + selector + "]";
Result.source = html;
Result.startOffset = $("body").html().indexOf(html);
Result.endOffset = Result.startOffset + html.length;
return Result;
}
The argument is the selector so you need to call the function like this:
var info = getInfo("#foo");
Upvotes: 0