如何使元素textarea自动彩色子字符串? [英] How to make the element textarea automatically color substrings?
问题描述
有一个< textarea>
在哪里可以写入,它会自动为 red
用红色?
它应该着色,即使它没有被空格包围。
例如,它应该仍然工作文本我吃了tha'red-meat
和单词 reddit
。
这是一个找到<$ c $的词语的完美场所
$ b div class =snippetdata-lang =jsdata-hide =falsedata-console =truedata-babel =false>
body {margin:0;} textarea {background-color:GhostWhite; border:0;高度:100%; outline:none; resize:none; width:100%;}
< textarea spellcheck = false>< / textarea>
您不能使用 textarea
,而是使用 contenteditable
span建议使用$ c> span 以避免输入<
的问题,并使用span来包装颜色子字符串。
var div = document.getElementById('div'); div.addEventListener (){//获取当前位置var pos = getCaretCharacterOffsetWithin(this); //获取内容中的所有单词this.innerHTML = this.innerText.replace(/ \w + / g,function(m){// create一个临时span元素var temp = document.createElement('span'); //将当前词设置为颜色temp.style.color = m; //检查颜色是否有效通过重新检查proeprty if(temp.style.color){//如果有效颜色,然后替换为temp元素html设置内容temp.innerHTML = m; return temp.outerHTML; } // else return the word itself return m; })//设置插入符位置setCaretPosition(this,pos);})//下面的代码从以下问题复制// http://stackoverflow.com/questions/26139475/restore-cursor-position-after-changing-contenteditablefunction getCaretCharacterOffsetWithin(element){var caretOffset = 0; var doc = element.ownerDocument || element.document; var win = doc.defaultView || doc.parentWindow; var sel; if(typeof win.getSelection!=undefined){sel = win.getSelection(); if(sel.rangeCount> 0){var range = win.getSelection()。getRangeAt(0); var preCaretRange = range.cloneRange(); preCaretRange.selectNodeContents(element); preCaretRange.setEnd(range.endContainer,range.endOffset); caretOffset = preCaretRange.toString()。length; }} else if((sel = doc.selection)&& sel.type!=Control){var textRange = sel.createRange(); var preCaretTextRange = doc.body.createTextRange(); preCaretTextRange.moveToElementText(element); preCaretTextRange.setEndPoint(EndToEnd,textRange); caretOffset = preCaretTextRange.text.length; } return caretOffset;} function setCaretPosition(element,offset){var range = document.createRange(); var sel = window.getSelection(); //选择适当的节点var currentNode = null; var previousNode = null; for(var i = 0; i 0){currentNode = currentNode.childNodes [0]; } //当前节点的calc偏移if(previousNode!= null){offset - = previousNode.length; } //检查当前节点是否具有足够的长度if(offset< = currentNode.length){break; }} //将光标移动到指定的偏移if(currentNode!= null){range.setStart(currentNode,offset); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); }}
< span contenteditable =trueid = div> sss< / span>
注意:从以下位置复制位置保留代码:更改contenteditable后恢复光标位置
更新:如果您只是要替换 red
在任何单词中,您可以这样做:
var div = document.getElementById('div'); div.addEventListener('input',function(){var pos = getCaretCharacterOffsetWithin(this); //获取所有红色小数, this.innerText.replace(/ red / g,'< span style =color:red> $&< / span>')setCaretPosition(this,pos);})//下面的问题// http://stackoverflow.com/questions/26139475/restore-cursor-position-after-changing-contenteditablefunction getCaretCharacterOffsetWithin(element){var caretOffset = 0; var doc = element.ownerDocument || element.document; var win = doc.defaultView || doc.parentWindow; var sel; if(typeof win.getSelection!=undefined){sel = win.getSelection(); if(sel.rangeCount> 0){var range = win.getSelection()。getRangeAt(0); var preCaretRange = range.cloneRange(); preCaretRange.selectNodeContents(element); preCaretRange.setEnd(range.endContainer,range.endOffset); caretOffset = preCaretRange.toString()。length; }} else if((sel = doc.selection)&& sel.type!=Control){var textRange = sel.createRange(); var preCaretTextRange = doc.body.createTextRange(); preCaretTextRange.moveToElementText(element); preCaretTextRange.setEndPoint(EndToEnd,textRange); caretOffset = preCaretTextRange.text.length; } return caretOffset;} function setCaretPosition(element,offset){var range = document.createRange(); var sel = window.getSelection(); //选择适当的节点var currentNode = null; var previousNode = null; for(var i = 0; i 0){currentNode = currentNode.childNodes [0]; } //当前节点的calc偏移if(previousNode!= null){offset - = previousNode.length; } //检查当前节点是否具有足够的长度if(offset< = currentNode.length){break; }} //将光标移动到指定的偏移if(currentNode!= null){range.setStart(currentNode,offset); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); }}
< span contenteditable =trueid = divstyle =width:100%; display:block> sss< / span>
$ b
注意:此解决方案存在一些与换行符相关的问题,因为内容是HTML,换行符没有任何意义。
What's the best way to have a <textarea>
where you can write and it automatically colors the word red
with the color red?
It should color it even if it's not surrounded by spaces.
So, for example, it should still work on the text I ate tha'red-meat
and on the word reddit
.
This is a perfect place to find words with red
in it.
I have the following code:
body {
margin: 0;
}
textarea {
background-color: GhostWhite;
border: 0;
height: 100%;
outline: none;
resize: none;
width: 100%;
}
<textarea spellcheck="false"></textarea>
You can't do it with textarea
, instead use a contenteditable
span(span
is suggested to avoid problem with entering <
) and wrap the color substring by using the span.
var div = document.getElementById('div');
div.addEventListener('input', function() {
// get the current position
var pos = getCaretCharacterOffsetWithin(this);
// get all word in the content
this.innerHTML = this.innerText.replace(/\w+/g, function(m) {
// create a temporary span element
var temp = document.createElement('span');
// set current word as color
temp.style.color = m;
// check color is valid by rechecking the proeprty
if (temp.style.color) {
// if valid color then replace with temp elements html after setting content
temp.innerHTML = m;
return temp.outerHTML;
}
// else return the word itself
return m;
})
// set caret position
setCaretPosition(this, pos);
})
// following code is copied from following question
// http://stackoverflow.com/questions/26139475/restore-cursor-position-after-changing-contenteditable
function getCaretCharacterOffsetWithin(element) {
var caretOffset = 0;
var doc = element.ownerDocument || element.document;
var win = doc.defaultView || doc.parentWindow;
var sel;
if (typeof win.getSelection != "undefined") {
sel = win.getSelection();
if (sel.rangeCount > 0) {
var range = win.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
caretOffset = preCaretRange.toString().length;
}
} else if ((sel = doc.selection) && sel.type != "Control") {
var textRange = sel.createRange();
var preCaretTextRange = doc.body.createTextRange();
preCaretTextRange.moveToElementText(element);
preCaretTextRange.setEndPoint("EndToEnd", textRange);
caretOffset = preCaretTextRange.text.length;
}
return caretOffset;
}
function setCaretPosition(element, offset) {
var range = document.createRange();
var sel = window.getSelection();
//select appropriate node
var currentNode = null;
var previousNode = null;
for (var i = 0; i < element.childNodes.length; i++) {
//save previous node
previousNode = currentNode;
//get current node
currentNode = element.childNodes[i];
//if we get span or something else then we should get child node
while (currentNode.childNodes.length > 0) {
currentNode = currentNode.childNodes[0];
}
//calc offset in current node
if (previousNode != null) {
offset -= previousNode.length;
}
//check whether current node has enough length
if (offset <= currentNode.length) {
break;
}
}
//move caret to specified offset
if (currentNode != null) {
range.setStart(currentNode, offset);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
<span contenteditable="true" id="div">sss</span>
NOTE : For position retaining code is copied from: Restore cursor position after changing contenteditable
UPDATE : In case you just want to replace red
within any word then you can do :
var div = document.getElementById('div');
div.addEventListener('input', function() {
var pos = getCaretCharacterOffsetWithin(this);
// get all red subtring and wrap it with span
this.innerHTML = this.innerText.replace(/red/g, '<span style="color:red">$&</span>')
setCaretPosition(this, pos);
})
// following code is copied from following question
// http://stackoverflow.com/questions/26139475/restore-cursor-position-after-changing-contenteditable
function getCaretCharacterOffsetWithin(element) {
var caretOffset = 0;
var doc = element.ownerDocument || element.document;
var win = doc.defaultView || doc.parentWindow;
var sel;
if (typeof win.getSelection != "undefined") {
sel = win.getSelection();
if (sel.rangeCount > 0) {
var range = win.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
caretOffset = preCaretRange.toString().length;
}
} else if ((sel = doc.selection) && sel.type != "Control") {
var textRange = sel.createRange();
var preCaretTextRange = doc.body.createTextRange();
preCaretTextRange.moveToElementText(element);
preCaretTextRange.setEndPoint("EndToEnd", textRange);
caretOffset = preCaretTextRange.text.length;
}
return caretOffset;
}
function setCaretPosition(element, offset) {
var range = document.createRange();
var sel = window.getSelection();
//select appropriate node
var currentNode = null;
var previousNode = null;
for (var i = 0; i < element.childNodes.length; i++) {
//save previous node
previousNode = currentNode;
//get current node
currentNode = element.childNodes[i];
//if we get span or something else then we should get child node
while (currentNode.childNodes.length > 0) {
currentNode = currentNode.childNodes[0];
}
//calc offset in current node
if (previousNode != null) {
offset -= previousNode.length;
}
//check whether current node has enough length
if (offset <= currentNode.length) {
break;
}
}
//move caret to specified offset
if (currentNode != null) {
range.setStart(currentNode, offset);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
<span contenteditable="true" id="div" style="width:100%;display:block">sss</span>
NOTE : This solution is holds some problem related to newline since the content is HTML and where newline doesn't have any meaning.
这篇关于如何使元素textarea自动彩色子字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!