【问题标题】:Javascript - Highlight specific text inside a string using onClick functionJavascript - 使用 onClick 函数突出显示字符串中的特定文本
【发布时间】:2017-10-19 08:45:58
【问题描述】:

假设我们有一个带有一些文本的 HTML 段落:

<p>Hello. This is a random paragraph with some not so random text inside of this paragraph</p>

我们有一个字符串数组:

const highlightThisWords = ['random', 'paragraph', 'inside']

我需要的是能够突出显示(更改样式)包含在数组内的段落内的文本的函数。请注意,单词段落在标签内有两次,但我只需要突出显示我单击的特定段落。我还需要在点击后进行一些计算,比如增加一个计数器。

环境:没有 jquery 的 React.js 可能

【问题讨论】:

  • 只有在您单击文本时才会填充数组? 注意单词段落在标签内有两次,但我只需要突出显示我点击的特定段落没有得到那个部分
  • 没有。它的预制阵列。我需要突出显示段落中与数组中的一个字符串相对应的文本
  • 在这种情况下,两个“段落”都需要突出显示不是吗?
  • 当我点击第一个时,只有第一个被突出显示。第二个也是一样。如果我没有点击第一个,而是点击了第二个,那么只有第二个会突出显示。或者当我同时点击它们时,它们都会突出显示

标签: javascript arrays reactjs search


【解决方案1】:

const highlightThisWords = ['random', 'paragraph', 'inside'];
const pNode = document.querySelector('p');

// turn pNode into a highlight-aware DOM
pNode.innerHTML = pNode.textContent.split(' ').map(word => {
  return highlightThisWords.includes(word) ? `<span>${word}</span>` : word;
}).join(' ');

const potentialHighlights = pNode.querySelectorAll('span');
potentialHighlights.forEach(highlightableWord => {
  highlightableWord.addEventListener('click', function(e) {
    // dehighlight all the rest
    pNode.querySelectorAll('.highlighted').forEach(highlighted => {
      highlighted.classList.remove('highlighted')
    });
    // highlight the clicked word
    highlightableWord.classList.add('highlighted');
  });
});
.highlighted {
  color: red;
}
&lt;p&gt;Hello. This is a random paragraph with some not so random text inside of this paragraph&lt;/p&gt;

您在上面找到了一个使用 vanilla js 的示例 sn-p,它为您的问题实现了一个最小的解决方案。没有人类理智的方法可以确定在段落中单击了哪个确切的单词,除非您将该单词包装在它自己的 html 标记中。到目前为止,建议的答案是将每个单词包装成一个标签。虽然这可行,但如果您有长段落(想象一下内存中的数千个 DOM 节点仅用于一个段落元素),它的性能就不会很好。我的建议是只在标签中包含“可能突出显示”的单词。

【讨论】:

  • 不得不为 React.js 修改很多,但这个想法效果最好
【解决方案2】:

您可以创建一个自定义组件并将该自定义组件用于使用“”拆分单词,但我确实尝试创建一个不是很干净的jsfiddle,但显示了它如何工作的演示。 要在这篇文章中显示代码:

class Hello extends React.Component {
  constructor() {
    super();
    this.handleClick = this.handleClick.bind(this);
  }
  split(str) {
    return str.split(" ");
  }
  make(str, i) {
    return <span key={i} style={{marginLeft:3}} onClick={this.handleClick}>{str}</span>;
  }
  handleClick(e) {
    console.log(this.props.highlights, e.target.innerText);
    if (this.props.highlights.indexOf(e.target.innerText) !== -1) {
      e.target.style.background = "red";
    }
  }
  render() {
    const parts = this.split(this.props.name);
    return <div>{parts.map((d, i) => {
        return this.make(d, i);
    })}</div>;
  }
}

ReactDOM.render(
  <Hello highlights={['random', 'paragraph', 'inside']} name="This is a random paragraph with some not so random text inside of this paragraph" />,
  document.getElementById('container')
);

【讨论】:

    【解决方案3】:

    由于您使用的是 React,您可以使用 String.prototype.split() 将整个文本拆分为单个单词的数组,然后使用条件渲染将它们呈现为突出显示或不突出显示:

    class MyComponent extends React.Component {
      render() {
        const arrayOfStrings = stringContainingParagraph.split(' ');
    
        return (
          <div>
            {arrayOfStrings.map((elem) => (
              ( highlightThisWords.indexOf(elem) !== -1 ) ?
              <mark>{elem}</mark> :
              <span>{elem}</span>
            ))}
          </div>
        );
      }
    }
    

    然后您可以根据需要自定义此代码(增加一个计数器,或使用onClicks 来获得您想要的功能)。

    【讨论】:

      猜你喜欢
      • 2018-03-05
      • 2011-09-04
      • 2018-10-16
      • 2021-12-12
      • 1970-01-01
      • 2010-12-08
      • 2016-10-18
      • 1970-01-01
      • 2019-09-13
      相关资源
      最近更新 更多