开发者

Modifying innerHTML in a contentEditable="true" DIV causes loss of focus or wrong selection

开发者 https://www.devze.com 2023-02-14 02:04 出处:网络
Here is the full page: <html> <head> <title>Test</title> <style type=\"text/css\">

Here is the full page:

<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>

The goal here is to highlight all numbers in red. (In the future I will actually 开发者_高级运维use a little more complicated coloring rules). Currently this color substitution is happening, but as soon as you add a number to the box, focus is lost.

Any hints? (Using Chorme dev)


Focus is being lost because clean2() manipulates the div. In FF the caret gets reset to the beginning of the editable div for the same reason. You can force the focus to stay by manually calling el.focus() in clean2(), however this will not fix the caret issue. You can set the caret position with something like:

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

However, this wont work for you because the "el" you need to set the cursor position in is the newly created text node. Unfortunately, the type of syntax highlighting you are trying to do is very complicated. If you wish to pursue it, check out:

Set cursor position on contentEditable <div>

Get caret position in contentEditable div


If you have to manipulate innerHTML like that, I'd suggest using the selection save and restore module from my Rangy library, which uses invisible elements to mark the beginning and end of the selection.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号