[英]Syntax highlight with JavaScript
I'm trying to make a simple syntax highlighter with JavaScript, but I always end up having the same problem. 我试图用JavaScript制作一个简单的语法荧光笔,但最终总是遇到相同的问题。 The program works as follows: as the user types enter (without the shift key) the program will replace the keyword var with another one with red color (this is still so basic). 该程序的工作方式如下:当用户输入时(不带Shift键),程序将用另一个红色的关键字替换var(这仍然很基本)。 The problem is that whenever you press enter, the text gets highlighted but the cursor returns to the first word of the first line. 问题在于,每当您按Enter键时,文本都会突出显示,但是光标会返回到第一行的第一个单词。 How do you think I can prevent this from happening? 您认为我如何防止这种情况发生?
<div class="container">
<pre class="text"><code contenteditable="true" id="format">
</code></pre>
</div>
JS JS
var editor = document.getElementById('format');
var npatt = / *var +/igm
editor.addEventListener('keyup', highlight);
function highlight(e){
var content = editor.innerHTML;
if(e.which === 13 && e.shiftKey===false){
editor.innerHTML = content.replace(npatt, '<span style="color:red">var</span> ');
console.log(editor.innerHTML);
}
}
Moving the cursor to the end of a contenteditable
element can be done according to the method in this answer . 可以根据此答案中的方法将光标移动到contenteditable
元素的末尾。 That approach uses the window.getSelection()
method to find the cursor position. 该方法使用window.getSelection()
方法查找光标位置。
I made a few changes to your code. 我对您的代码做了一些更改。
test
check to see if the regular expression even matches the content to avoid calling replace
and setting editor.innerHTML
on every Enter keystroke as the original code did. 添加了一个test
检查,以查看正则表达式是否与内容匹配,从而避免像原始代码一样在每个Enter键上调用replace
和editor.innerHTML
。 cursorManager.setEndOfContenteditable
method (from the answer referenced above) to reset the cursor to the end of the editor after the replace
operation. 添加了对cursorManager.setEndOfContenteditable
方法的调用(来自上面引用的答案),以在replace
操作之后将游标重置到编辑器的末尾。 Here is the updated code. 这是更新的代码。
var editor = document.getElementById('format');
var npatt = / *var +/igm;
editor.addEventListener('keyup', highlight);
function highlight(e){
var content = editor.innerHTML;
if(e.which === 13 && e.shiftKey === false && npatt.test(content)) {
editor.innerHTML = content.replace(npatt, '<span style="color:red">var</span> ');
cursorManager.setEndOfContenteditable(editor);
}
}
And here is a working example. 这是一个有效的示例。
var editor = document.getElementById('format'); var npatt = / *var +/igm; editor.addEventListener('keyup', highlight); function highlight(e){ var content = editor.innerHTML; if(e.which === 13 && e.shiftKey === false && npatt.test(content)) { editor.innerHTML = content.replace(npatt, '<span style="color:red">var</span> '); cursorManager.setEndOfContenteditable(editor); } } //Code to set the cursor position modified from this answer: https://stackoverflow.com/a/19588665/830125 //Namespace management idea from http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/ (function( cursorManager ) { //From: http://www.w3.org/TR/html-markup/syntax.html#syntax-elements var voidNodeTags = ['AREA', 'BASE', 'BR', 'COL', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'MENUITEM', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR', 'BASEFONT', 'BGSOUND', 'FRAME', 'ISINDEX']; //From: https://stackoverflow.com/questions/237104/array-containsobj-in-javascript Array.prototype.contains = function(obj) { var i = this.length; while (i--) { if (this[i] === obj) { return true; } } return false; } //Basic idea from: https://stackoverflow.com/questions/19790442/test-if-an-element-can-contain-text function canContainText(node) { if(node.nodeType == 1) { //is an element node return !voidNodeTags.contains(node.nodeName); } else { //is not an element node return false; } }; function getLastChildElement(el){ var lc = el.lastChild; while(lc && lc.nodeType != 1) { if(lc.previousSibling) lc = lc.previousSibling; else break; } return lc; } //Based on Nico Burns's answer cursorManager.setEndOfContenteditable = function(contentEditableElement) { var range,selection; if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+ { range = document.createRange();//Create a range (a range is a like the selection but invisible) range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start selection = window.getSelection();//get the selection object (allows you to change selection) selection.removeAllRanges();//remove any selections already made selection.addRange(range);//make the range you have just created the visible selection } else if(document.selection)//IE 8 and lower { range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible) range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start range.select();//Select the range (make it the visible selection } } }( window.cursorManager = window.cursorManager || {}));
<div class="container"> <pre class="text"><code contenteditable="true" id="format"> </code></pre> </div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.