我目前正在尝试为Javascript创建语法突出显示工具,并且我目前面临的问题是创建这样的东西很常见,该问题是在用户键入或编辑时将插入标记的位置设置到最后contentEditable文本。
我在SO上研究并发现了this和许多其他解决方案,但没有一个有效。它会获得插入符号的位置,但永远不会重置它,因此我正在尝试寻找解决此问题的方法。
下面是我想出的代码。
html
<div id="editor" contentEditable="true" onkeyup="resetPosition(this)"></div>
<input type="text" onkeyup="resetPosition(this)" />
js
function getPos(e) {
// for contentedit field
if (e.isContentEditable) {
e.focus()
let _range = document.getSelection().getRangeAt(0)
let range = _range.cloneRange()
range.selectNodeContents(e)
range.setEnd(_range.endContainer, _range.endOffset)
return range.toString().length;
}
// for texterea/input element
return e.target.selectionStart
}
function setPos(pos, e) {
// for contentedit field
if (e.isContentEditable) {
e.focus()
document.getSelection().collapse(e, pos);
return
}
e.setSelectionRange(pos, pos)
}
function resetPosition(e) {
if(e.isContentEditable) {
let currentPosition = getPos(e);
e.innerHTML=e.innerHTML.replace(/[0-9]/g, "a");
setPos(currentPosition, e);
return;
}
e.value = e.value.replace(/[0-9]/g, "a");
setPos(currentPosition, e);
}
这对于文本输入很好,但对contentEditable divs
无效。
[当我输入类似function
的内容时,我得到otincfun
。
UPDATE:我可以通过将这一行从setPos
更改为document.getSelection().collapse(e, pos);
来修复document.getSelection().collapse(e.firstChild, pos);
功能,但是出现了一个新的错误。
当我按ENTER键时,插入符号返回到第一行和第一个字符。请如何解决?
下面是小提琴链接
https://jsfiddle.net/oketega/bfeh9nm5/35/
谢谢。
[document.getSelection().collapse(element, index)
将光标折叠到index
指向的子节点,而不是字符索引。
我能够通过将此行从
setPos
更改为document.getSelection().collapse(e, pos);
来修复document.getSelection().collapse(e.firstChild, pos);
功能>如果仅替换字符,则可以使用,但是如果要创建语法突出显示器,则需要将字符括在
span
元素中以设置样式。然后,e.firstChild
只会将位置设置为e
的第一个子对象内的索引,不包括后一个span
的
[另一件事是,您可能需要自动完成某些字符。在操作文本之前,插入符的位置可能与在操作之后的插入符位置不同。
我建议创建一个<span id="caret-position"></span>
元素以跟踪插入符号的位置。
它会像这样:
function textChanged(element) { // 1 const text = setCursorMarker(element.innerText, element); // 2 const html = manipulate(text); element.innerHTML = html; // 3 const index = findCursorIndex(element); document.getSelection().collapse(element, index) }
- 每次用户键入时,您都可以获取当前的插入符号位置并在其中的
#caret-position
元素中滑动。
#caret-position
在哪里,并将插入号放在那里。注意:当用户键入内容可编辑元素时,建议的监听方式是使用
oninput
监听器,而不是onkeyup
。按住一个键可以插入许多字符。示例
这里有一个有效的js小提琴:https://jsfiddle.net/Vehmloewff/0j8hzevm/latest/
已知问题:两次按下Enter
后,它将失去对插入符号应该位于的位置的跟踪。我不太确定为什么要这么做。