У меня есть этот скрипт, добавляющий новый интервал внутри редактируемого div каждый раз, когда пользователь вводит точку во входном тексте, пытаясь отделить текст, написанный в разных интервалах, на основе наличия разделяющей их точки.(Я использую пользовательский тег 'mytag', но на самом деле он ведет себя как span)
<div style="border:1px solid black;" id='editor-container' contenteditable="true"><mytag id="0">test</mytag></div>
JS:
var divContainer = document.getElementById("editor-container");
var nodeIdIncrement = 0;
var htmlBefore = divContainer.innerHTML;
var html;
var editedCharIndex;
moveCursorOnDiv("0");
divContainer.addEventListener("input", function(e) {
html=divContainer.innerHTML;
editedCharIndex=findFirstDiffPos(htmlBefore,html);
console.log("html[editedCharIndex]: "+html[editedCharIndex]);
if(html[editedCharIndex]=="."){
nodeIdIncrement++;
htmlBefore=html.substring(0, editedCharIndex+1)+'</mytag><mytag id="'+nodeIdIncrement+'">'+html.substring(editedCharIndex+1);
divContainer.innerHTML = htmlBefore;
moveCursorOnDiv(nodeIdIncrement);
}else{
htmlBefore = divContainer.innerHTML;
}
}, false);
// Find index of newly added character making a diff between previuos situation and present one
function findFirstDiffPos(a, b) {
var shorterLength = Math.min(a.length, b.length);
for (var i = 0; i < shorterLength; i++){
if (a[i] !== b[i]) return i;
}
if (a.length !== b.length) return shorterLength;
return -1;
}
function moveCursorOnDiv(divId){
console.log("divId: "+divId);
var el = document.getElementById(divId);
console.log("inner: "+el.innerHTML);
var range = document.createRange();
var sel = window.getSelection();
range.setStart(el, 0);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
Здесь это JSFIDDLE
Допустим, я ввел символ 'A' в редактируемом div "editor-container", результат будет:
<div style="border:1px solid black;" id="editor-container" contenteditable="true">
<mytag id="0">A</mytag>
</div>
Затем я добавлю точку.Результат будет:
<div style="border:1px solid black;" id="editor-container" contenteditable="true">
<mytag id="0">A.</mytag>
<mytag id="1"></mytag>
</div>
Когда точка будет добавлена, я программно (функция moveCursorOnDiv) заставляю курсор перемещаться по новому div.Ожидаемым результатом будет то, что ввод другого символа 'B' приведет к ситуации:
<div style="border:1px solid black;" id="editor-container" contenteditable="true">
<mytag id="0">A.</mytag>
<mytag id="1">B</mytag>
</div>
Вместо этого это фактически приведет к Chrome в:
<div style="border:1px solid black;" id="editor-container" contenteditable="true">
<mytag id="0">A.B</mytag>
<mytag id="1"></mytag>
</div>
В то время как в Firefox ведет себя как ожидалось90% раз, но иногда случайным образом ведет себя как в Chrome.
Итак, если у меня есть курсор между двумя соседними промежутками, как html решит, будет ли следующий вход помещен в промежуток или в другой?Есть способ вызвать ожидаемое поведение?
РЕДАКТИРОВАТЬ: Совершенно очевидно, что это происходит только в том случае, если следующий div пуст, поскольку есть неоднозначность.Если вы поместите символ в следующий div и переместите каретку в положение «1», она будет работать как шарм.(Просто чтобы сказать, что проблема не зависит напрямую от этого конкретного кода, который в разных условиях работает идеально)
JSFIDDLE 2
Это также означает, что проблема может бытьрешено добавить что-то вроде & nb sp;при добавлении нового div, но это не чистое решение.