最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - highlight searching text on type react - Stack Overflow

programmeradmin2浏览0评论

I try to highlight text in a input on typing, I use two method in this case. As I understand I need return on search something like this: <mark>${item}<mark/>

fuzzyContains = (text, search) => {
        debugger
        if (!text)
            return false
        if (!search)
            return true

        search = search.toLowerCase()
        text = text.toString().toLowerCase()

        let previousLetterPosition = -1

        return search.split('').every(s => {
            debugger
            previousLetterPosition = text.indexOf(s, previousLetterPosition + 1)

            return previousLetterPosition !== -1
        })
    }

    handleSearch = search => {
        const {data} = this.state
        debugger
        let filteredData = data.filter(x => Object.keys(x).some(key => {
            debugger
            this.fuzzyContains(x[`<mark>${key}<mark/>`], search)}))

        this.setState({filteredData, search})
    }

I try to highlight text in a input on typing, I use two method in this case. As I understand I need return on search something like this: <mark>${item}<mark/>

fuzzyContains = (text, search) => {
        debugger
        if (!text)
            return false
        if (!search)
            return true

        search = search.toLowerCase()
        text = text.toString().toLowerCase()

        let previousLetterPosition = -1

        return search.split('').every(s => {
            debugger
            previousLetterPosition = text.indexOf(s, previousLetterPosition + 1)

            return previousLetterPosition !== -1
        })
    }

    handleSearch = search => {
        const {data} = this.state
        debugger
        let filteredData = data.filter(x => Object.keys(x).some(key => {
            debugger
            this.fuzzyContains(x[`<mark>${key}<mark/>`], search)}))

        this.setState({filteredData, search})
    }
Share Improve this question edited Aug 17, 2017 at 13:48 Palaniichuk Dmytro asked Aug 17, 2017 at 13:40 Palaniichuk DmytroPalaniichuk Dmytro 3,18313 gold badges39 silver badges69 bronze badges 3
  • 1 Please explain the use-case a bit better. Your explanation is too vague as it currently stands. What do you mean by "search" exactly? You want a substring highlighted as you are typing in a text-input? – Chris Commented Aug 17, 2017 at 13:43
  • @Chris yes when typing in a text-input – Palaniichuk Dmytro Commented Aug 17, 2017 at 13:47
  • Simply store the entered text in a variable in the render method. use javascript's split method by words and add css styling to each word inside of a map function. – fungusanthrax Commented Aug 17, 2017 at 16:04
Add a ment  | 

1 Answer 1

Reset to default 7

The code you provide is too little to understand what's actually going on in your app. Instead, I have made a simple example below.


In the following snippet I start by creating an application with a fixed text and an input element. The input element has a listener that has an onChange trigger. Whenever you type something, the changeInput function is fired.

The function starts by getting the innerText of the related DOM node where the text is printed. It then tries to find your entered substring with indexOf. If there's a match, we split the string into three pieces (the matching text, and the substrings before and after that matching text, if any).

If there is no match, we reset the text back to the initial value.

The whole thing is then entered into an array; the 1st and 3rd items are plain strings, whereas the 2nd item (the match) is a React Element of type strong which is used to highlight the matching text.

class MyApp extends React.Component {
  constructor() {
    super();
    this.initialText = "Lorem ipsum dolor sit amet";
    this.state = {
      text: this.initialText,
      inputValue: ""
    };
  }
  changeInput = (e) => {
    let value = e.target.value;
    let txt = document.getElementById("myText").innerText;
    let idx = txt.indexOf(value);
    if(idx >= 0) {
      let newText = [txt.substring(0, idx), <strong>{txt.substring(idx, idx + value.length)}</strong>, txt.substring(idx + value.length)];
      this.setState({inputValue: value, text: newText});
    } else {
      this.setState({inputValue: value, text: this.initialText});
    }    
  }
  render() {
    return (
      <div>
        <p id="myText">{this.state.text}</p>
        <input onChange={this.changeInput} value={this.state.inputValue} />
      </div>
    );
  }
}

ReactDOM.render(<MyApp />, document.getElementById("app"));
strong {
  background: red;
  color: white;
  font-weight: inherit;
}
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>


Note that this can be done with using refs if you prefer. If you want to avoid DOM lookups and the use of refs, you could always use 2 state variables; one that holds the resulting JSX and one that holds the plain text representation.

Also note that this will only highlight the first matching substring. For example, if you had the string: "Lorem ipsum, Lorem ipsum", and you searched for "Lorem", only the first occurrence of that word would be highlighted. If you want multiple hightlights, you could try using some kind of regex.

发布评论

评论列表(0)

  1. 暂无评论