更改文本区域中特定单词的颜色
Change color of specific words in textarea
我正在构建一个 Sql 查询生成器,并希望在用户输入 SELECT、FROM、WHERE 等字词时更改文本区域中字词的文本颜色。
我已经搜索了一些,超出了这个范围 (https://jsfiddle.net/qcykvr8j/2/) 不幸的是我没有进一步搜索。
示例代码
HTML:
<textarea name="query_field_one" id="query_field_one" onkeyup="checkName(this)"></textarea>
JS:
function checkName(el)
{
if (el.value == "SELECT" ||
el.value == "FROM" ||
el.value == "WHERE" ||
el.value == "LIKE" ||
el.value == "BETWEEN" ||
el.value == "NOT LIKE" ||
el.value == "FALSE" ||
el.value == "NULL" ||
el.value == "TRUE" ||
el.value == "NOT IN")
{
el.style.color='orange'
}
else {
el.style.color='#FFF'
}
}
JSFiddle:
https://jsfiddle.net/qcykvr8j/2/
但是这个例子在我进一步输入时删除了颜色。
我要的是这个:
我已经尝试将 Keyup 与 jQuery 中的 Contains 结合使用,但效果不佳。
键盘输入:https://api.jquery.com/keyup/
包含:https://api.jquery.com/contains-selector/
我希望有人可以帮助我提供示例或网站,以便我找到更多信息。
此致,詹斯
您无法更改 <textarea>
中单词的颜色,但可以使用 contenteditable
属性制作 <div>
、<span>
或 <p>
看起来像 <textarea>
.
为此,您可以使用 JavaScript 插件,但如果您想创建一个新插件,下面的代码可能会对您有所帮助。
为此,您需要获取文本中的任何单词。然后检查它是否是 SQL 关键字。
// SQL keywords
var keywords = ["SELECT","FROM","WHERE","LIKE","BETWEEN","NOT LIKE","FALSE","NULL","FROM","TRUE","NOT IN"];
// Keyup event
$("#editor").on("keyup", function(e){
// Space key pressed
if (e.keyCode == 32){
var newHTML = "";
// Loop through words
$(this).text().replace(/[\s]+/g, " ").trim().split(" ").forEach(function(val){
// If word is statement
if (keywords.indexOf(val.trim().toUpperCase()) > -1)
newHTML += "<span class='statement'>" + val + " </span>";
else
newHTML += "<span class='other'>" + val + " </span>";
});
$(this).html(newHTML);
// Set cursor postion to end of text
var child = $(this).children();
var range = document.createRange();
var sel = window.getSelection();
range.setStart(child[child.length-1], 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
this.focus();
}
});
#editor {
width: 400px;
height: 100px;
padding: 10px;
background-color: #444;
color: white;
font-size: 14px;
font-family: monospace;
}
.statement {
color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editor" contenteditable="true"></div>
HTML-
<div id="board" class="original" contenteditable="true"></div>
<div id="dummy" class="original"></div>
CSS-
.original {
position:absolute;width: 50%; margin: 0 auto; padding: 1em;background: #fff;height:100px;margin:2px;border:1px solid black;color:#fff;overflow:auto;
}
#dummy{
color:black;
}
#board{
z-index:11;background:transparent;color:transparent;caret-color: black;
}
.original span.highlighted {
color:red;
}
JAVASCRIPT -
var highLightedWord = ["select","insert","update","from","where"];
var regexFromMyArray = new RegExp(highLightedWord.join("|"), 'ig');
$('#board').keyup(function(event){
document.getElementById('dummy').innerHTML = $('#board').html().replace(regexFromMyArray,function(str){
return '<span class="highlighted">'+str+'</span>'
})
})
var target = $("#dummy");
$("#board").scroll(function() {
target.prop("scrollTop", this.scrollTop)
.prop("scrollLeft", this.scrollLeft);
});
使用 Vanilla JS,您可以这样做:
// SQL keywords
var keywords = ["SELECT", "FROM", "WHERE", "LIKE", "BETWEEN", "UNION", "FALSE", "NULL", "FROM", "TRUE", "NOT", "ORDER", "GROUP", "BY", "NOT", "IN"];
// Keyup event
document.querySelector('#editor').addEventListener('keyup', e => {
// Space key pressed
if (e.keyCode == 32) {
var newHTML = "";
// Loop through words
str = e.target.innerText;
chunks = str
.split(new RegExp(
keywords
.map(w => `(${w})`)
.join('|'), 'i'))
.filter(Boolean),
markup = chunks.reduce((acc, chunk) => {
acc += keywords.includes(chunk.toUpperCase()) ?
`<span class="statement">${chunk}</span>` :
`<span class='other'>${chunk}</span>`
return acc
}, '')
e.target.innerHTML = markup;
// Set cursor postion to end of text
// document.querySelector('#editor').focus()
var child = e.target.children;
var range = document.createRange();
var sel = window.getSelection();
range.setStart(child[child.length - 1], 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
this.focus();
}
});
#editor {
width: 400px;
height: 100px;
padding: 10px;
background-color: #444;
color: white;
font-size: 14px;
font-family: monospace;
}
.statement {
color: orange;
}
<div id="editor" contenteditable="true"></div>
您可以使用此代码
<code contenteditable="true">
<span style="color: orange">SELECT</span> *
<span style="color: orange">FROM</span>
TABLE
<span style="color: orange">WHERE</span>
id = 2
</code>
这不是此问题的答案,但它回答了标题问题,当您 google 搜索有关在文本区域中突出显示单词时会发现该问题。
可以使用 built-in API setSelectionRange 函数和 ::selection css 选择器在文本区域元素中进行彩色选择。
注意,它一次只支持一个文本选择,并且只支持文本区域获得焦点。
const input = document
.getElementById( 'text-box' );
var i, l;
input.focus();
input.value = input.value.trim();
i = input.value .indexOf( 'programming' );
l = ( 'programming' ).length;
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange
input
.setSelectionRange( i, l + i );
::-moz-selection {
background-color: yellow;
color: red;
}
::selection {
background-color: yellow;
color: red;
}
<textarea id="text-box" size="40">
I like programming with JavaScript!
</textarea>
我无法对插入符号做任何事情,所以我借用了其他人的工作,这使代码变得有点庞大。我不知道它有多快,但效果很好 :T
我借用的代码:
https://jsfiddle.net/nrx9yvw9/5/
Get a range's start and end offset's relative to its parent container
你可以 运行 而没有 jquery:
//(sorry for the grammer mistakes)
/*Caret function sources: https://jsfiddle.net/nrx9yvw9/5/ &&
function createRange(e,t,n){if(n||((n=document.createRange()).selectNode(e),n.setStart(e,0)),0===t.count)n.setEnd(e,t.count);else if(e&&t.count>0)if(e.nodeType===Node.TEXT_NODE)e.textContent.length<t.count?t.count-=e.textContent.length:(n.setEnd(e,t.count),t.count=0);else for(var o=0;o<e.childNodes.length&&(n=createRange(e.childNodes[o],t,n),0!==t.count);o++);return n}function getCurrentCaretPosition(e){var t,n=0,o=e.ownerDocument||e.document,a=o.defaultView||o.parentWindow;if(void 0!==a.getSelection){if((t=a.getSelection()).rangeCount>0){var r=a.getSelection().getRangeAt(0),c=r.cloneRange();c.selectNodeContents(e),c.setEnd(r.endContainer,r.endOffset),n=c.toString().length}}else if((t=o.selection)&&"Control"!=t.type){var i=t.createRange(),g=o.body.createTextRange();g.moveToElementText(e),g.setEndPoint("EndToEnd",i),n=g.text.length}return n}function setCurrentCaretPosition(e,t){if(t>=0){var n=window.getSelection();range=createRange(e,{count:t}),range&&(range.collapse(!1),n.removeAllRanges(),n.addRange(range))}}
/*Caret functions end*/
/*
* -> required | [...,...] -> example | {...} -> value type | || -> or
id: Position of words for where they should be colored [undefined,0,1,...] {int||string}
color: Color for words [aqua,rgba(0,255,0,1),#ff25d0] {string}
fontStyle: Font style for words [italic,oblique,normal] {string}
decoration: Text decoration for words [underlined,blink,dashes] {string}
* words: Words that should be colored {array}
*/
var keywords = [
{
color: "orange",
words: [
"SELECT",
"FROM",
"WHERE",
"LIKE",
"BETWEEN",
"NOT",
"FALSE",
"NULL",
"TRUE",
"IN",
],
},
{
id: 0,
color: "red",
fontStyle: "italic",
decoration: "underline",
words: ["TEST"],
},
];
//defining node object as "editor"
var editor = document.getElementById("editor");
//listening editor for keyup event
editor.addEventListener("keyup", function (e) {
// if ctrl or alt or shift or backspace and keyname's length is not 1, don't check
if( e.ctrlKey || e.altKey || ( e.key.length - 1 && e.key != "Backspace" ) || ( e.shiftKey && e.char ) ) return;
//getting caret position for applying it in the end, because after checking and coloring done; it's gonna be at the beginning.
pos = getCurrentCaretPosition(this);
text = this.innerText; //getting input's just text value
words = text.split(/\s/gm); //splitting it from all whitespace characters
for (var i = 0; i < keywords.length; i++)
for (var n = 0; n < words.length; n++) {
//looks for is word in our "keywords"' object and check's position if it's id entered
if (keywords[i].words.indexOf(words[n].toUpperCase().trim()) > -1 && (keywords[i].id >= 0 ? keywords[i].id == n : true) )
//applys options to word
words[n] = `<span style="color:${ keywords[i].color ?? "white" };font-style:${ keywords[i].fontStyle ?? "normal" };text-decoration:${ keywords[i].decoration ?? "normal" }">${words[n]}</span>`;
}
//joining array elements with whitespace caracter and apply it to input
this.innerHTML = words.join(" ");
//restoring caret position
setCurrentCaretPosition(this, pos);
});
#editor {
width: 400px;
height: 100px;
padding: 10px;
background-color: #444;
color: white;
font-size: 14px;
font-family: monospace;
font-weight: normal;
caret-color: white;
}
<div id="editor" spellcheck="false" contenteditable="true"></div>
// SQL keywords
var keywords = ["SELECT","FROM","WHERE","LIKE","BETWEEN","NOT LIKE","FALSE","NULL","FROM","TRUE","NOT IN"];
// Keyup event
$("#editor").on("keyup", function(e){
// Space key pressed
if (e.keyCode == 32){
var newHTML = "";
// Loop through words
$(this).text().replace(/[\s]+/g, " ").trim().split(" ").forEach(function(val){
// If word is statement
if (keywords.indexOf(val.trim().toUpperCase()) > -1)
newHTML += "<span class='statement'>" + val + " </span>";
else
newHTML += "<span class='other'>" + val + " </span>";
});
$(this).html(newHTML);
// Set cursor postion to end of text
var child = $(this).children();
var range = document.createRange();
var sel = window.getSelection();
range.setStart(child[child.length-1], 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
this.focus();
}
});
#editor {
width: 400px;
height: 100px;
padding: 10px;
background-color: #444;
color: white;
font-size: 14px;
font-family: monospace;
}
.statement {
color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editor" contenteditable="true"></div>
我找到了另一个独特的解决方案,与其他解决方案相比,它非常简单。基本上这个想法是将一些突出显示的代码放在文本区域后面,并使文本区域除了插入符号外不可见。
我用https://github.com/jgnewman/custom-syntax-highlighter定义了我自己的语言。想怎么用就怎么用。
此处描述了这个想法,但我添加了一个最小示例:https://css-tricks.com/creating-an-editable-textarea-that-supports-syntax-highlighted-code/您仍应阅读此处以解决滚动问题
尝试在下面输入以下内容:callFunction('with string')
//on reload the textarea will still contain text. We have to put that into the code element and format the text
function init() {
update(document.getElementById('editing').value);
}
window.onload = init;
function update(text) {
//put textarea content into code tags
let result_element = document.querySelector('#highlighting-content');
result_element.innerText = text;
// Syntax Highlight define your own Regex. Names will be css classes to stile
highlight({
patterns: [{
name: 'string',
match: /^(\'[^\'\n]*\')/,
},
{
name: 'fn-call',
match: [/^([A-z_]+)\(/, '', '('],
},
],
});
}
html,
body {
margin: 0px;
padding: 0px;
height: 100%;
}
.container {
display: grid;
height: 100%;
margin: 0px;
padding: 0px;
}
pre,
code {
white-space: pre-line;
/*Remove indetend on first line*/
}
#editing,
#highlighting {
/*position above each other*/
grid-column: 1;
grid-row: 1;
margin: 0px;
padding: 0px;
/*make sure to apply text styling to both*/
font-size: 15pt;
font-family: monospace;
line-height: 20pt;
}
#editing {
color: transparent;
background: transparent;
caret-color: white;
color: transparent;
}
/*syntax highlighting class names defined in js code*/
.fn-call {
color: red;
}
.string {
color: blue;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/custom-syntax-highlighter@latest/bin/index.js"></script>
<script>
var highlight = window.csHighlight; //need to initialize the library
</script>
</head>
<body>
<!--Container is display grid to position textarea and code above each other-->
<div class="container">
<!--the code element that will be highlighted-->
<pre id="highlighting" aria-hidden="true">
<code id="highlighting-content">
</code>
</pre>
<!--make sure the textarea is in front and can be interacted with. disable spell check-->
<textarea id="editing" spellcheck="false" oninput="update(this.value);"></textarea>
</div>
</body>
</html>
祝你有愉快的一天
我正在构建一个 Sql 查询生成器,并希望在用户输入 SELECT、FROM、WHERE 等字词时更改文本区域中字词的文本颜色。
我已经搜索了一些,超出了这个范围 (https://jsfiddle.net/qcykvr8j/2/) 不幸的是我没有进一步搜索。
示例代码
HTML:
<textarea name="query_field_one" id="query_field_one" onkeyup="checkName(this)"></textarea>
JS:
function checkName(el)
{
if (el.value == "SELECT" ||
el.value == "FROM" ||
el.value == "WHERE" ||
el.value == "LIKE" ||
el.value == "BETWEEN" ||
el.value == "NOT LIKE" ||
el.value == "FALSE" ||
el.value == "NULL" ||
el.value == "TRUE" ||
el.value == "NOT IN")
{
el.style.color='orange'
}
else {
el.style.color='#FFF'
}
}
JSFiddle:
https://jsfiddle.net/qcykvr8j/2/
但是这个例子在我进一步输入时删除了颜色。
我要的是这个:
我已经尝试将 Keyup 与 jQuery 中的 Contains 结合使用,但效果不佳。
键盘输入:https://api.jquery.com/keyup/
包含:https://api.jquery.com/contains-selector/
我希望有人可以帮助我提供示例或网站,以便我找到更多信息。
此致,詹斯
您无法更改 <textarea>
中单词的颜色,但可以使用 contenteditable
属性制作 <div>
、<span>
或 <p>
看起来像 <textarea>
.
为此,您可以使用 JavaScript 插件,但如果您想创建一个新插件,下面的代码可能会对您有所帮助。
为此,您需要获取文本中的任何单词。然后检查它是否是 SQL 关键字。
// SQL keywords
var keywords = ["SELECT","FROM","WHERE","LIKE","BETWEEN","NOT LIKE","FALSE","NULL","FROM","TRUE","NOT IN"];
// Keyup event
$("#editor").on("keyup", function(e){
// Space key pressed
if (e.keyCode == 32){
var newHTML = "";
// Loop through words
$(this).text().replace(/[\s]+/g, " ").trim().split(" ").forEach(function(val){
// If word is statement
if (keywords.indexOf(val.trim().toUpperCase()) > -1)
newHTML += "<span class='statement'>" + val + " </span>";
else
newHTML += "<span class='other'>" + val + " </span>";
});
$(this).html(newHTML);
// Set cursor postion to end of text
var child = $(this).children();
var range = document.createRange();
var sel = window.getSelection();
range.setStart(child[child.length-1], 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
this.focus();
}
});
#editor {
width: 400px;
height: 100px;
padding: 10px;
background-color: #444;
color: white;
font-size: 14px;
font-family: monospace;
}
.statement {
color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editor" contenteditable="true"></div>
HTML-
<div id="board" class="original" contenteditable="true"></div>
<div id="dummy" class="original"></div>
CSS-
.original {
position:absolute;width: 50%; margin: 0 auto; padding: 1em;background: #fff;height:100px;margin:2px;border:1px solid black;color:#fff;overflow:auto;
}
#dummy{
color:black;
}
#board{
z-index:11;background:transparent;color:transparent;caret-color: black;
}
.original span.highlighted {
color:red;
}
JAVASCRIPT -
var highLightedWord = ["select","insert","update","from","where"];
var regexFromMyArray = new RegExp(highLightedWord.join("|"), 'ig');
$('#board').keyup(function(event){
document.getElementById('dummy').innerHTML = $('#board').html().replace(regexFromMyArray,function(str){
return '<span class="highlighted">'+str+'</span>'
})
})
var target = $("#dummy");
$("#board").scroll(function() {
target.prop("scrollTop", this.scrollTop)
.prop("scrollLeft", this.scrollLeft);
});
使用 Vanilla JS,您可以这样做:
// SQL keywords
var keywords = ["SELECT", "FROM", "WHERE", "LIKE", "BETWEEN", "UNION", "FALSE", "NULL", "FROM", "TRUE", "NOT", "ORDER", "GROUP", "BY", "NOT", "IN"];
// Keyup event
document.querySelector('#editor').addEventListener('keyup', e => {
// Space key pressed
if (e.keyCode == 32) {
var newHTML = "";
// Loop through words
str = e.target.innerText;
chunks = str
.split(new RegExp(
keywords
.map(w => `(${w})`)
.join('|'), 'i'))
.filter(Boolean),
markup = chunks.reduce((acc, chunk) => {
acc += keywords.includes(chunk.toUpperCase()) ?
`<span class="statement">${chunk}</span>` :
`<span class='other'>${chunk}</span>`
return acc
}, '')
e.target.innerHTML = markup;
// Set cursor postion to end of text
// document.querySelector('#editor').focus()
var child = e.target.children;
var range = document.createRange();
var sel = window.getSelection();
range.setStart(child[child.length - 1], 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
this.focus();
}
});
#editor {
width: 400px;
height: 100px;
padding: 10px;
background-color: #444;
color: white;
font-size: 14px;
font-family: monospace;
}
.statement {
color: orange;
}
<div id="editor" contenteditable="true"></div>
您可以使用此代码
<code contenteditable="true">
<span style="color: orange">SELECT</span> *
<span style="color: orange">FROM</span>
TABLE
<span style="color: orange">WHERE</span>
id = 2
</code>
这不是此问题的答案,但它回答了标题问题,当您 google 搜索有关在文本区域中突出显示单词时会发现该问题。
可以使用 built-in API setSelectionRange 函数和 ::selection css 选择器在文本区域元素中进行彩色选择。
注意,它一次只支持一个文本选择,并且只支持文本区域获得焦点。
const input = document
.getElementById( 'text-box' );
var i, l;
input.focus();
input.value = input.value.trim();
i = input.value .indexOf( 'programming' );
l = ( 'programming' ).length;
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange
input
.setSelectionRange( i, l + i );
::-moz-selection {
background-color: yellow;
color: red;
}
::selection {
background-color: yellow;
color: red;
}
<textarea id="text-box" size="40">
I like programming with JavaScript!
</textarea>
我无法对插入符号做任何事情,所以我借用了其他人的工作,这使代码变得有点庞大。我不知道它有多快,但效果很好 :T
我借用的代码:
https://jsfiddle.net/nrx9yvw9/5/
Get a range's start and end offset's relative to its parent container
你可以 运行 而没有 jquery:
//(sorry for the grammer mistakes)
/*Caret function sources: https://jsfiddle.net/nrx9yvw9/5/ &&
function createRange(e,t,n){if(n||((n=document.createRange()).selectNode(e),n.setStart(e,0)),0===t.count)n.setEnd(e,t.count);else if(e&&t.count>0)if(e.nodeType===Node.TEXT_NODE)e.textContent.length<t.count?t.count-=e.textContent.length:(n.setEnd(e,t.count),t.count=0);else for(var o=0;o<e.childNodes.length&&(n=createRange(e.childNodes[o],t,n),0!==t.count);o++);return n}function getCurrentCaretPosition(e){var t,n=0,o=e.ownerDocument||e.document,a=o.defaultView||o.parentWindow;if(void 0!==a.getSelection){if((t=a.getSelection()).rangeCount>0){var r=a.getSelection().getRangeAt(0),c=r.cloneRange();c.selectNodeContents(e),c.setEnd(r.endContainer,r.endOffset),n=c.toString().length}}else if((t=o.selection)&&"Control"!=t.type){var i=t.createRange(),g=o.body.createTextRange();g.moveToElementText(e),g.setEndPoint("EndToEnd",i),n=g.text.length}return n}function setCurrentCaretPosition(e,t){if(t>=0){var n=window.getSelection();range=createRange(e,{count:t}),range&&(range.collapse(!1),n.removeAllRanges(),n.addRange(range))}}
/*Caret functions end*/
/*
* -> required | [...,...] -> example | {...} -> value type | || -> or
id: Position of words for where they should be colored [undefined,0,1,...] {int||string}
color: Color for words [aqua,rgba(0,255,0,1),#ff25d0] {string}
fontStyle: Font style for words [italic,oblique,normal] {string}
decoration: Text decoration for words [underlined,blink,dashes] {string}
* words: Words that should be colored {array}
*/
var keywords = [
{
color: "orange",
words: [
"SELECT",
"FROM",
"WHERE",
"LIKE",
"BETWEEN",
"NOT",
"FALSE",
"NULL",
"TRUE",
"IN",
],
},
{
id: 0,
color: "red",
fontStyle: "italic",
decoration: "underline",
words: ["TEST"],
},
];
//defining node object as "editor"
var editor = document.getElementById("editor");
//listening editor for keyup event
editor.addEventListener("keyup", function (e) {
// if ctrl or alt or shift or backspace and keyname's length is not 1, don't check
if( e.ctrlKey || e.altKey || ( e.key.length - 1 && e.key != "Backspace" ) || ( e.shiftKey && e.char ) ) return;
//getting caret position for applying it in the end, because after checking and coloring done; it's gonna be at the beginning.
pos = getCurrentCaretPosition(this);
text = this.innerText; //getting input's just text value
words = text.split(/\s/gm); //splitting it from all whitespace characters
for (var i = 0; i < keywords.length; i++)
for (var n = 0; n < words.length; n++) {
//looks for is word in our "keywords"' object and check's position if it's id entered
if (keywords[i].words.indexOf(words[n].toUpperCase().trim()) > -1 && (keywords[i].id >= 0 ? keywords[i].id == n : true) )
//applys options to word
words[n] = `<span style="color:${ keywords[i].color ?? "white" };font-style:${ keywords[i].fontStyle ?? "normal" };text-decoration:${ keywords[i].decoration ?? "normal" }">${words[n]}</span>`;
}
//joining array elements with whitespace caracter and apply it to input
this.innerHTML = words.join(" ");
//restoring caret position
setCurrentCaretPosition(this, pos);
});
#editor {
width: 400px;
height: 100px;
padding: 10px;
background-color: #444;
color: white;
font-size: 14px;
font-family: monospace;
font-weight: normal;
caret-color: white;
}
<div id="editor" spellcheck="false" contenteditable="true"></div>
// SQL keywords
var keywords = ["SELECT","FROM","WHERE","LIKE","BETWEEN","NOT LIKE","FALSE","NULL","FROM","TRUE","NOT IN"];
// Keyup event
$("#editor").on("keyup", function(e){
// Space key pressed
if (e.keyCode == 32){
var newHTML = "";
// Loop through words
$(this).text().replace(/[\s]+/g, " ").trim().split(" ").forEach(function(val){
// If word is statement
if (keywords.indexOf(val.trim().toUpperCase()) > -1)
newHTML += "<span class='statement'>" + val + " </span>";
else
newHTML += "<span class='other'>" + val + " </span>";
});
$(this).html(newHTML);
// Set cursor postion to end of text
var child = $(this).children();
var range = document.createRange();
var sel = window.getSelection();
range.setStart(child[child.length-1], 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
this.focus();
}
});
#editor {
width: 400px;
height: 100px;
padding: 10px;
background-color: #444;
color: white;
font-size: 14px;
font-family: monospace;
}
.statement {
color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editor" contenteditable="true"></div>
我找到了另一个独特的解决方案,与其他解决方案相比,它非常简单。基本上这个想法是将一些突出显示的代码放在文本区域后面,并使文本区域除了插入符号外不可见。
我用https://github.com/jgnewman/custom-syntax-highlighter定义了我自己的语言。想怎么用就怎么用。
此处描述了这个想法,但我添加了一个最小示例:https://css-tricks.com/creating-an-editable-textarea-that-supports-syntax-highlighted-code/您仍应阅读此处以解决滚动问题
尝试在下面输入以下内容:callFunction('with string')
//on reload the textarea will still contain text. We have to put that into the code element and format the text
function init() {
update(document.getElementById('editing').value);
}
window.onload = init;
function update(text) {
//put textarea content into code tags
let result_element = document.querySelector('#highlighting-content');
result_element.innerText = text;
// Syntax Highlight define your own Regex. Names will be css classes to stile
highlight({
patterns: [{
name: 'string',
match: /^(\'[^\'\n]*\')/,
},
{
name: 'fn-call',
match: [/^([A-z_]+)\(/, '', '('],
},
],
});
}
html,
body {
margin: 0px;
padding: 0px;
height: 100%;
}
.container {
display: grid;
height: 100%;
margin: 0px;
padding: 0px;
}
pre,
code {
white-space: pre-line;
/*Remove indetend on first line*/
}
#editing,
#highlighting {
/*position above each other*/
grid-column: 1;
grid-row: 1;
margin: 0px;
padding: 0px;
/*make sure to apply text styling to both*/
font-size: 15pt;
font-family: monospace;
line-height: 20pt;
}
#editing {
color: transparent;
background: transparent;
caret-color: white;
color: transparent;
}
/*syntax highlighting class names defined in js code*/
.fn-call {
color: red;
}
.string {
color: blue;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/custom-syntax-highlighter@latest/bin/index.js"></script>
<script>
var highlight = window.csHighlight; //need to initialize the library
</script>
</head>
<body>
<!--Container is display grid to position textarea and code above each other-->
<div class="container">
<!--the code element that will be highlighted-->
<pre id="highlighting" aria-hidden="true">
<code id="highlighting-content">
</code>
</pre>
<!--make sure the textarea is in front and can be interacted with. disable spell check-->
<textarea id="editing" spellcheck="false" oninput="update(this.value);"></textarea>
</div>
</body>
</html>
祝你有愉快的一天