I have this script adding a new span inside an editable div each time the user input a dot in the input text, trying to separate text written in different spans based on the presence of a dot separating them. (I use a custom tag 'mytag' but it behaves actually like a 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);
}
Here it is the JSFIDDLE
Let's say I input a char 'A' in the editable div "editor-container" the result will be:
<div style="border:1px solid black;" id="editor-container" contenteditable="true">
<mytag id="0">A</mytag>
</div>
Then I add a dot. The result will be:
<div style="border:1px solid black;" id="editor-container" contenteditable="true">
<mytag id="0">A.</mytag>
<mytag id="1"></mytag>
</div>
When the dot gets added, I force programatically (function moveCursorOnDiv) the cursor to move on the new div. The expected result would be that input an another character 'B' would result in situation:
<div style="border:1px solid black;" id="editor-container" contenteditable="true">
<mytag id="0">A.</mytag>
<mytag id="1">B</mytag>
</div>
Instead it actually result in Chrome in:
<div style="border:1px solid black;" id="editor-container" contenteditable="true">
<mytag id="0">A.B</mytag>
<mytag id="1"></mytag>
</div>
While in Firefox behaves as expected 90% of times, but sometimes randomly behaves as in Chrome.
So, if I have the cursor between two adjacent span how html decide if the next input will be put in a span or in the other? There's a way to force the expected behaviour?
EDIT: Pretty obviously, this happens only in case the following div is empty for there is ambiguity. If you put a char in the following div and move the caret in position '1' it works like a charm. (Just to say that the problem is not directly dependent from this specific code, which under different conditions works perfectly)
This means also the problem can be solved adding something like a &nb sp; when adding a new div, but it not a clean solution.
from In case of two adjacent editable span and the cursor being in the middle, how html decide on which one i'm writing?
No comments:
Post a Comment