如何使用React根据用户输入来突出显示文本? [英] How to highlight text based on user input with React?

查看:47
本文介绍了如何使用React根据用户输入来突出显示文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们简单地讨论一下带有 contenteditable ="true" 的准系统可编辑< div> 的简单情况:

Let's take the simple case of a barebones editable <div> with contenteditable="true":

<div contenteditable="true">
  Edit this 
</div>

用户可以输入/编辑/删除< div> 元素的内容.

The user is able to input/edit/delete the contents of this <div> element.

对于某些输入形式,如果用户输入的文本大于字符数限制,则超过此限制的字符将被突出显示(警告用户停止添加文本).

For certain input forms, if the user inputs text greater than some limit of characters, the characters added over this limit will be highlighted (warning the user to stop adding text).

如何用React实现类似的目的?

How could I achieve something like this with React?

我认为< span> 可以用于突出显示文本,但是我无法概念化在达到字符数限制后如何开始突出显示.

I think <span> could be used to highlight the text, but I cannot conceptualize how to begin the highlighting after the character count limit has been reached.

请让我知道问题是否明确.谢谢您的帮助.

Please let me know if the question is clear. Thank you for the help.

推荐答案

您可以通过签入 onchange 事件(div文本长度)来到达并用跨度包裹多余的文本,然后通过串联文本(不包含多余的字符)+包裹的多余文本跨度再次设置该div的内部html;

You could reach by checking in the onchange event, the div text length and wrap extra text by a span and set inner html of that div again by concatenatin text (without extra chars) + wrapped extra text span;

(由于xss注入,不建议使用innerHTML,但这是我发现的唯一解决方案)

这里的主要问题是一旦设置了div innerHTML,光标将停留在div文本的开头,因此我做了一些技巧,使用

that main problem here is once setting div innerHTML , your cursor will rest to start of div text , so i've done a little trick to set selection at the end of the text using

       // get textt par before extra text
      let start =  html.slice(0, MAX_LENGTH ) ;
      // get extra text
      let overflow =  html.slice(MAX_LENGTH) ;
      // rap extra text by span
      overflow = `<span style="color:${COLOR}">${overflow}</span>`;
      //set text as innerHTML (or use dangerouslyINerHTML with sate var)
      ref.current.innerHTML = start+overflow
      
      // below part is to set cursor , at the end after inner html 
      // because innerHTML will reset selection to the start of div text
      let range = document.createRange()
      var sel = window.getSelection()
      range.setStart(ref.current.lastChild, 1   )

      sel.removeAllRanges()
      sel.addRange(range)

请参见此处,使用带有特殊道具的snnipet示例创建了一个组件并使用了不同的道具

See here working snnipet with deiferent props example created a component and use different props

const { useRef } = React;

/* create Eitable Component */
const EditAbleDiv  =( props ) => {
  // get max length from props
  const MAX_LENGTH = props.maxLength || 40;
  // get color from props
  const COLOR = props.warningColor || 'orange';
  
  let ref = useRef(null);
  
  
  // on change event
  const contentChange = (e) => {
    
    // get only text without html tags
    let html = e.target.innerText;
    
    if (html.length > MAX_LENGTH) {

      // get textt par before extra text
      let start =  html.slice(0, MAX_LENGTH ) ;
      // get extra text
      let overflow =  html.slice(MAX_LENGTH) ;
      // rap extra text by span
      overflow = `<span style="color:${COLOR}">${overflow}</span>`;
      //set text as innerHTML (or use dangerouslyINerHTML with sate var)
      ref.current.innerHTML = start+overflow
      
      // below part is to set cursor , at the end after inner html 
      // because innerHTML will reset selection to the start of div text
      let range = document.createRange()
      var sel = window.getSelection()
      range.setStart(ref.current.lastChild, 1   )

      sel.removeAllRanges()
      sel.addRange(range)

    }
  }

  return <div  ref={ref}
  contentEditable 
  onInput={contentChange} 
  >
    Edit text
</div>
}
/* end component */


function App() {
  
  return (
    <div>
      <b> click in below div to edit text </b> <br/><br/>
      <EditAbleDiv maxLength={25} />
      <hr />
      <EditAbleDiv maxLength={18} warningColor={"red"} />
      <hr />
      <EditAbleDiv maxLength={12} warningColor={"green"} />
    </div>
  )
}

ReactDOM.render(
    <App />,
    document.body
);

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

这篇关于如何使用React根据用户输入来突出显示文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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