如何在没有外部库的情况下语法突出显示内容可编辑的div?

时间:2018-09-15 17:40:43

标签: javascript html css html5

我正试图制作一个具有实时语法突出显示功能(如 Visual Studio Code )的Web文本编辑器,但是问题是当我尝试突出显示时,它会将光标放在编辑器的后面。

我的代码:

<html>
<head>
    <title>Code</title>
    <style>
        body {
            margin:0px;
            padding:0px;
            overflow:hidden;
        }
        #code {
            background:#2b2e33;
            color:white;
            font-family:Monaco;
            width:100%;
            height:100%;
            font-size:12px;
        }
    </style>
</head>
<body>
    <div id="code" contenteditable="true"></div>
    <script>
        var div = document.getElementById("code");
        setInterval(function() {
            var code = div.innerText;
            code = code.replace("var","<span style='color:magenta'>var</span>");
            div.innerHTML = code;
        },100)
    </script>
</body>

光标似乎移到了后面,文本被倒转,没有明显的原因……

1 个答案:

答案 0 :(得分:0)

您的问题是每100毫秒重新运行一次代码。这意味着光标将在开始时自动聚焦,并且最终将使用大量资源。我已更改此设置以在按空格键时运行该功能。其次,我添加了一个功能,将插入号放在行的末尾。

var div = document.getElementById('code');


window.onkeydown = function(event) {
  if (event.keyCode === 32) {
    var code = div.innerText;
    coded = code.replace("<span style='color:magenta'>" + code + "</span>");

    div.innerHTML = coded;

    placeCaretAtEnd(div);
  }
};

function placeCaretAtEnd(el) {
  el.focus();
  if (typeof window.getSelection != "undefined" &&
    typeof document.createRange != "undefined") {
    var range = document.createRange();
    range.selectNodeContents(el);
    range.collapse(false);
    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
  } else if (typeof document.body.createTextRange != "undefined") {
    var textRange = document.body.createTextRange();
    textRange.moveToElementText(el);
    textRange.collapse(false);
    textRange.select();
  }
}
body {
  margin: 0px;
  padding: 0px;
  overflow: hidden;
}

#code {
  background: #2b2e33;
  color: white;
  font-family: sans serif;
  width: 100vw;
  height: 100vh;
  font-size: 15px;
}
<html>

<head>
  <title>Code</title>
</head>

<body>
  <div id="code" contenteditable="true"></div>
</body>

</html>