如何使元素textarea自动彩色子字符串? [英] How to make the element textarea automatically color substrings?

查看:84
本文介绍了如何使元素textarea自动彩色子字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个< 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆