修改contentEditable =“true”DIV中的innerHTML会导致焦点丢失或选择错误

时间:2011-03-02 04:51:09

标签: javascript html contenteditable

以下是整页:

<html>
<head>
<title>Test</title>
<style type="text/css">
  .edit { border: 1px solid blue; font-size: 20pt }
</style>
<script type="text/javascript">
  function clean(id) {
    setTimeout('clean2("'+id+'")', 1)
  }
  function clean2(id) {
    el=document.getElementById(id)
    off=window.getSelection().anchorOffset
    el.innerHTML = el.innerHTML.replace(/(<([^>]+)>)/ig,""); 
    el.innerHTML = el.innerHTML.replace(/([0-9])/ig,"<font color='red'>$1</font>");
    return false;
  }
</script>
</head>

<body onload="document.getElementsByClassName('edit')[0].focus()">

<h1>Type in here</h1>
<div id="e1" class="edit" contentEditable="true" onkeyup="clean('e1')"></div>

</body>
</html>

这里的目标是突出显示所有红色数字。 (将来我会使用更复杂的着色规则)。目前正在进行此颜色替换,但只要您在框中添加数字,焦点就会丢失。

任何提示? (使用Chorme dev)

2 个答案:

答案 0 :(得分:4)

焦点正在丢失,因为clean2()操纵div。在FF中,由于同样的原因,插入符号被重置为可编辑div的开头。 您可以通过在clean2()中手动调用el.focus()来强制关注焦点,但这不会解决插入符问题。 您可以使用以下内容设置插入位置:

window.getSelection().removeAllRanges();
var range = document.createRange();
range.setStart(el,start)
range.setEnd(el,start);
window.getSelection().addRange(range);

但是,这对你不起作用,因为你需要设置光标位置的“el”是新创建的文本节点。不幸的是,您尝试做的语法突出显示的类型非常复杂。如果您想继续学习,请查看:

Set cursor position on contentEditable <div>

Get caret position in contentEditable div

答案 1 :(得分:1)

如果您必须像这样操纵innerHTML,我建议您使用selection save and restore module库中的Rangy,该库使用不可见元素标记选择的开头和结尾。