javascript - 使用 contenteditable 突出显示文本,可更一致地在移动浏览器上运行
问题描述
我目前正在使用 contenteditable 来创建一个输入字段,其中一些单词用颜色突出显示,一些单词被替换为特定符号。它在桌面浏览器和一些移动浏览器上完美运行。但是,它不适用于例如。Firefox Focus,以及某些版本的移动版 Chrome 和 Firefox?有时字母没有被输入,然后突然一堆字母被重复。这很奇怪,仅在使用软件键盘时才会发生,而不是物理键盘。
我目前正在这样做,并尝试了这些功能的大量不同变体,但它并没有真正产生影响。
function handleInput(event: Event) {
const target = event.target as HTMLInputElement;
const cursorPos = getCursorPos(target);
const [highlighted, offset] = highlight(target.textContent);
target.innerHTML = highlighted;
setCursorPos(target, cursorPos - offset);
}
function getCursorPos(element: HTMLInputElement): number {
const shadowRoot = calculatorElement.getRootNode() as ShadowRoot;
const range = shadow.getRange(shadowRoot);
//const selection = shadowRoot.getSelection();
//const range = selection.getRangeAt(0);
const preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
return preCaretRange.toString().length;
}
function setCursorPos(element: HTMLElement, indexToSelect: number) {
const range = document.createRange();
range.selectNodeContents(element);
const textNodes = getTextNodesIn(element);
let nodeEndPos = 0;
for (const textNode of textNodes) {
const previousNodeEndPos = nodeEndPos;
nodeEndPos += textNode.length;
// If the index that should be selected is
// less than or equal to the current position (the end of the text node),
// then the index points to somewhere inside the current text node.
// This text node along with indexToSelect will then be used when setting the cursor position.
if (indexToSelect <= nodeEndPos) {
range.setStart(textNode, indexToSelect - previousNodeEndPos);
range.setEnd(textNode, indexToSelect - previousNodeEndPos);
break;
}
}
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
function getTextNodesIn(node: Node): Text[] {
const textNodes: Text[] = [];
// If it's text node, add it to the list directly,
// otherwise go through it recursively and find text nodes within it.
if (node.nodeType == Node.TEXT_NODE) {
textNodes.push(node as Text);
} else {
for (const child of node.childNodes) {
textNodes.push(...getTextNodesIn(child));
}
}
return textNodes;
}
实际上是否有可能让它在移动浏览器中一致地工作?我已经注意到其他输入字段的这个问题,我在网上找到了这样的突出显示。
解决方案
推荐阅读
- powerbi - 计算月份级别的上个月值
- react-native - 如何在第一次渲染时获取 setState 后的评论值?
- python - 初学者应该知道哪些常见的 Python 命名约定?
- docker - 带有 ' | 之类的符号的 Docker 问题 ' 在 Windows 10 专业版中
- c - 根据两个字段的值对链表中的结构进行排序
- sql - 从 StartDate 列表中推断结束日期
- multithreading - 写入 CSV 时如何解决“短写”错误
- oracle-apex - 无法从条形图中为页面项目分配值以进行内联弹出
- python - Python在循环混淆中生成随机数
- sql - Sybase中JOIN和Inner JOIN的区别