以下はこの回答に基づいていますが、任意のドキュメント (iframe 内のドキュメントなど) の選択で動作するように変更されています。その回答で説明されているこのアプローチの素朴さに関する同じ警告が引き続き適用されます。
function getCaretCharacterOffsetWithin(element) {
var doc = element.ownerDocument || element.document;
var win = doc.defaultView || doc.parentWindow;
var sel, range, preCaretRange, caretOffset = 0;
if (typeof win.getSelection != "undefined") {
sel = win.getSelection();
if (sel.rangeCount) {
range = sel.getRangeAt(0);
preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
caretOffset = preCaretRange.toString().length;
}
} else if ( (sel = doc.selection) && sel.type != "Control") {
range = doc.selection.createRange();
preCaretRange = doc.body.createTextRange();
preCaretRange.moveToElementText(element);
preCaretRange.setEndPoint("EndToEnd", textRange);
caretOffset = preCaretTextRange.text.length;
}
return caretOffset;
}
使用例:
var iframe = document.getElementById("foo");
var iframeBody = (iframe.contentDocument || iframe.contentWindow.document).body;
alert( getCaretCharacterOffsetWithin(iframeBody) );