我需要在contenteditablediv中实现数字的突出显示(将来我会添加更复杂的规则)。问题是当我用JavaScript替换插入新内容时,DOM更改和contenteditablediv失去了焦点。我需要的是将div放在当前位置上,以使注意力集中在div上,这样用户就可以键入而不会出现任何问题,而我的功能只需突出显示数字即可。谷歌搜索我认为Rangy库是最好的解决方案。我有以下代码:
function formatText() {
var savedSel = rangy.saveSelection();
el = document.getElementById('pad');
el.innerHTML = el.innerHTML.replace(/(<([^>]+)>)/ig,"");
el.innerHTML = el.innerHTML.replace(/([0-9])/ig,"<font color='red'>$1</font>");
rangy.restoreSelection(savedSel);
}
<div contenteditable="true" id="pad" onkeyup="formatText();"></div>
问题是功能结束工作的重点重新回到div之后,但是插入符号始终指向div开始,我可以在任何地方键入,除了div开始。下面还有console.log类型,Rangywarning: Module SaveRestore: Marker element has been removed. Cannot restore selection.
请帮助我实现此功能。我对另一种解决方案开放,不仅是杂乱无章的图书馆。谢谢!
这是jsfiddle,但无法正常工作(当我在div中键入数字时什么也没有发生),dunno也许是我(通过jsfiddle首次发布代码)或资源不支持contenteditable。UPD*我在stackoverflow上读到类似的问题,但是解决方案不适合我的情况:(
问题在于,Rangy的保存/恢复选择模块通过将不可见的标记元素插入到选择边界所在的DOM中来工作,然后您的代码会去除所有HTML标签,包括Rangy的标记元素(如错误消息所示)。您有两种选择:
innerHTML
。这将更可靠,但涉及更多。更新
我已经为Rangy(上面的选项2)取消了基于字符索引的选择保存/恢复。这有点粗糙,但是可以解决这种情况。它通过遍历文本节点来工作。我可以以某种形式将其添加到Rangy中。(
码:
function saveSelection(containerEl) {
var charIndex = 0, start = 0, end = 0, foundStart = false, stop = {};
var sel = rangy.getSelection(), range;
function traverseTextNodes(node, range) {
if (node.nodeType == 3) {
if (!foundStart && node == range.startContainer) {
start = charIndex + range.startOffset;
foundStart = true;
}
if (foundStart && node == range.endContainer) {
end = charIndex + range.endOffset;
throw stop;
}
charIndex += node.length;
} else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
traverseTextNodes(node.childNodes[i], range);
}
}
}
if (sel.rangeCount) {
try {
traverseTextNodes(containerEl, sel.getRangeAt(0));
} catch (ex) {
if (ex != stop) {
throw ex;
}
}
}
return {
start: start,
end: end
};
}
function restoreSelection(containerEl, savedSel) {
var charIndex = 0, range = rangy.createRange(), foundStart = false, stop = {};
range.collapseToPoint(containerEl, 0);
function traverseTextNodes(node) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
range.setStart(node, savedSel.start - charIndex);
foundStart = true;
}
if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
range.setEnd(node, savedSel.end - charIndex);
throw stop;
}
charIndex = nextCharIndex;
} else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
traverseTextNodes(node.childNodes[i]);
}
}
}
try {
traverseTextNodes(containerEl);
} catch (ex) {
if (ex == stop) {
rangy.getSelection().setSingleRange(range);
} else {
throw ex;
}
}
}
function formatText() {
var el = document.getElementById('pad');
var savedSel = saveSelection(el);
el.innerHTML = el.innerHTML.replace(/(<([^>]+)>)/ig,"");
el.innerHTML = el.innerHTML.replace(/([0-9])/ig,"<font color='red'>$1</font>");
// Restore the original selection
restoreSelection(el, savedSel);
}
我正在使用一个具有许多不同库依赖关系的gradle项目,并使用新的清单合并。在我的
我正在使用此Composer包进行需要此包提供的功能的开发。寻找替代方案,我发现这是我最好的选择,因为可用的替代方案太简单了,无法在我处理的时间限制下实现。 现在,我已经在运行PHP 5.5的本地机器(在LinuxWindows 10的子系统上)和运行PHP 5.6的个人服务器上测试了它,但是正式服运行PHP 5.4,由于原因无法升级。 首先我犯了这个错误: 在寻找解决方案时,我遇到了这个问题,因
问题内容: 我在Python中有一个SymPy表达式,我想将其复制并粘贴到Java源代码中。问题在于,对幂有不同的表示法: Java用途; Python使用。 所以我的问题是:有没有办法以“ Java格式”打印SymPy表达式? 问题答案: SymPy有几个专门用于此目的的代码打印机。虽然没有Java代码打印机,但是有一种Javascript打印机。我不能说Java和Javascript是否在每种
问题内容: 我正在从hibernate4.2.17迁移到5.0.7,到目前为止效果还不错,但是似乎该方法已被弃用。我就是不能使用它了。 这是我的代码: 我替换了所有其他方法,但找不到完全替代的方法… 错误消息:该方法是未定义的交易类型 问题答案: 按照5.0 Javadoc :
问题内容: 一个非常简单的小问题,但是我不太明白该怎么做。 我需要将’_’的每个实例替换为空格,并将’#’的每个实例替换为空/空。 我已经试过了: 我真的不喜欢这样的链接命令。还有另一种方法可以做到这一点吗? 问题答案: 使用OR运算符(): 您还可以使用字符类: Fiddle 如果您想用一件事替换哈希值,而用另一件事替换下划线,则只需要链接即可。但是,您可以添加一个原型: 但是为什么不连锁呢?我
我真的不喜欢这样链接命令。有没有另一种方法在一个做?