每当用户在输入文本中输入一个点时,我都会让这个脚本在可编辑的 div 中添加一个新的 span,并尝试根据是否存在分隔它们的点来分隔不同 span 中编写的文本。 (我使用自定义标签“mytag”,但它实际上表现得像一个跨度)
<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
假设我在可编辑的 div“editor-container”中输入一个字符“A”,结果将是:
<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 中那样随机运行。
那么,如果我的光标位于两个相邻的 span 之间,html 如何决定下一个输入是放在一个 span 还是另一个? 有办法强制执行预期的行为吗?
编辑: 很明显,只有在以下 div 因含糊不清而为空的情况下才会发生这种情况。如果你在下面的 div 中放置一个 char 并将插入符号移动到位置“1”,它就像一个魅力。 (只是说问题不直接依赖于这个特定的代码,它在不同的条件下完美运行)
这也意味着问题可以通过添加像 &nb sp; 这样的东西来解决。添加新的 div 时,但这不是一个干净的解决方案。
最佳答案
首先:你设置<div id="editor-container".....> </div>
可编辑所以当你输入 .
它正在创建一个新的 <mytag>
有了新的 Id
但它没有为新的 <mytag>
提供可编辑选项由于它不可编辑,因此鼠标指针保持在相同位置。
这里我做了一些改动:添加了一些边框和外边距,使其可见
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+'" contenteditable="true" style="margin: 10px;">'+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);
}
mytag {
border: 1px solid black;
}
<div id='editor-container'>
<mytag id="0" contenteditable="true">test</mytag>
</div>
在 JS 中在这里做了修改:
htmlBefore=html.substring(0, editedCharIndex+1)+'</mytag><mytag id="'+nodeIdIncrement+'" contenteditable="true" style="margin: 10px; border: 1px solid black;">'+html.substring(editedCharIndex+1);
关于javascript - 如果两个相邻的可编辑范围和光标在中间,html 如何决定我正在写哪一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56441839/