突出搜索文本类型反应

时间:2017-08-17 13:40:51

标签: javascript reactjs ecmascript-6

我尝试在输入中突出显示输入中的文本,在这种情况下我使用两种方法。据我所知,我需要返回搜索内容:<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})
    }

1 个答案:

答案 0 :(得分:6)

您提供的代码太少,无法理解应用中实际发生的情况。相反,我在下面做了一个简单的例子。

在下面的代码片段中,我首先创建一个包含固定文本和输入元素的应用程序。 input元素有一个具有onChange触发器的侦听器。无论何时输入内容,都会触发changeInput函数。

该函数首先获取打印文本的相关DOM节点的innerText。然后,它会尝试使用indexOf查找您输入的子字符串。如果匹配,我们将字符串分成三部分(匹配的文本,以及匹配文本之前和之后的子字符串,如果有的话)。

如果没有匹配,我们会将文本重置为初始值。

然后将整个事物输入数组;第1和第3项是纯字符串,而第2项(匹配)是strong类型的反应元素,用于突出显示匹配的文本。

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.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

请注意,如果您愿意,可以使用refs完成此操作。如果你想避免使用DOM查找和refs的使用,你总是可以使用2个状态变量;一个持有生成的JSX,另一个持有纯文本表示。

另请注意,这只会突出显示第一个匹配的子字符串。例如,如果您有字符串:“Lorem ipsum,Lorem ipsum”,并且您搜索了“Lorem”,则只会突出显示该单词的第一个匹配项。如果你想要多个高亮点,你可以尝试使用某种正则表达式。