Вот лучшее решение, которое я придумал, надеюсь, это поможет кому-то вниз по дороге, которая с помощью Ace или CodeMirror в сочетании с contenteditable:
Setup (для новичков)
Мы можем получить, когда пользователь выбирает с помощью:
var sel = document.getSelection();
Начало выбора называется «якорь» , а конец называется «фокус». Например, , когда вы выберете несколько слов текста, есть начало и конец выделения.
var anchorPoint = elementPointInCode(sel.anchorNode, sel.anchorOffset);
var focusPoint = elementPointInCode(sel.focusNode, sel.focusOffset);
Поскольку HTML содержит тег и читаемый текст, есть смещения. Например:
<p>abcdefgh</p>
// ...^
Смещение - это индекс в строке текстового узла. В нашем примере буква «d» смещена на 4 символа от точки входа & gtp & lt тег. Но смещение нулевой точки, так что смещение фактически 3.
Мы получаем смещение с помощью:
var offset = sel.anchorOffset;
// -- or --
var offset = sel.focusOffset;
... в зависимости от того, что мы хотим, начало конца.
Функции
function elementPointInCode(element, offset) {
// There may or may not be an offset.
offset = offset || 0;
var node = element;
// Process first node because it'll more-than-likely be a text node.
// And we don't want to go matching text against any of the node HTML.
// e.g. <a href="page.html">page 1</a>
// where the text "page" sould match the "page" within the <a> attributes.
var strIndex;
var str;
// Bump text nodes up to parent
if(node.nodeType == 3) {
node = node.parentNode;
str = node.outerHTML;
strIndex = str.indexOf(">") + offset + 1;
} else {
strIndex = ;
}
// This will ultimately contain the HTML string of the root node.
var parentNodeStr = "";
while(node){
// Get the current node's HTML.
var str = node.outerHTML;
// Preemptively snag the parent
var parent = node.parentNode;
if(parent && str){
// The <html> root, we won't have a parent.
var outer = parent.outerHTML;
if(outer){
// Stash the node's HTML for post processing.
parentNodeStr = outer;
// Cumulatively count the offset's within each node
strIndex += parentNodeStr.indexOf(str);
}
}
// Work our way up to the root
node = parent;
}
// Chop the root HTML by our cumulative string index
var str = parentNodeStr.substr(0, strIndex);
var Astr = str.split("\n");
return {
row : Astr.length,
col : Astr.pop().length
}
};
два пенни примечание: 'doc.documentElement.outerHTML;' даст вам вычисленный HTML, а не оригинальный источник .html файла, строки могут не совпадать. (один способ может прочитать исходный файл из XHR) – Kaiido
Я согласен и имею новое решение. Благодарю. – bob