简体   繁体   English

高亮匹配文本过滤器 javascript

[英]Highlight matching text filter javascript

I'm doing a search filter highlight.我正在做一个搜索过滤器突出显示。 But it renders [object Object] instead of <mark>match values</mark> when replacing the values.但它在替换值时呈现[object Object]而不是<mark>match values</mark>

Currently I have this code.目前我有这个代码。

this.countries.response.filter((val) => {
  const position = val.value.toLowerCase().indexOf(this.controls.country.toLowerCase());
  if (this.controls.country == "") {
    return val;
  } else if (position !== -1) {
    return val;
  }
}).map((e) => {
    const position = e.value.toLowerCase().indexOf(this.controls.country.toLowerCase());
    let matches = e.value.substring(position, this.controls.country.length + position);
    const regex = new RegExp(matches, 'gi');
    const highlighted = e.value.replace(regex, '<mark>'+{matches}+'</mark>');
      return (
        <li class="lov-val list-group-item">
          <p>{highlighted}</p>
        </li>
    )
})

And I am having this output.我有这个 output。 在此处输入图像描述

I'm doing something like this.我正在做这样的事情。

在此处输入图像描述

You're seeing [object Object] because you're appending an object to your string with {matches} .您看到[object Object]是因为您使用{matches}将 object 附加到您的字符串中。 You should do something like '<mark>' + matches + '</mark>' so that you append a string instead.您应该执行类似'<mark>' + matches + '</mark>'操作,以便 append 改为字符串。

However that probably won't fix the issue.但是,这可能无法解决问题。 I suspect you'll still see the string '<mark>EXAMPLE_TEXT</mark>' in your output instead of actual html.我怀疑您仍然会在 output 中看到字符串'<mark>EXAMPLE_TEXT</mark>' ,而不是实际的 html。 This is because text content containing valid html is just interpreted as text, the browser won't parse it as html.这是因为包含有效 html 的文本内容只是被解释为文本,浏览器不会将其解析为 html。

It looks like you're writing jsx , so I'm assuming you're using React.看起来您正在编写jsx ,所以我假设您正在使用 React。 An easy fix would be to use the dangerouslySetInnerHTML prop.一个简单的解决方法是使用dangerouslySetInnerHTML道具。 However there are security concerns with using this (hence the cautious name) so use it at your own discretion.但是,使用它存在安全问题(因此是谨慎的名称),因此请自行决定使用它。

I don't have an immediate alternative at mind, but I imagine there should be some way to break up each country string into separate components without having to use dangerouslySetInnerHTML and regex replace shenanigans.我没有直接的替代方案,但我想应该有某种方法可以将每个国家/地区字符串分解为单独的组件,而不必使用dangerouslySetInnerHTML的 SetInnerHTML 和正则表达式替换恶作剧。

eg例如

<span>
  <span>
    SOUTH
  </span>
  <mark>
    AME // this is the part that's highlighted
  </mark>
  <span>
    RICA
  </span>
</span>

Without knowing all your code, I suspect you are only missing one step.在不知道所有代码的情况下,我怀疑您只缺少一步。 You get an HTMLCollection.你得到一个 HTMLCollection。 You have to iterate this and enclose the match - as you already did correctly - with mark.您必须对其进行迭代并将匹配 - 正如您已经正确完成的那样 - 用标记括起来。

Here is an example that makes it even clearer for you.这是一个让您更清楚的示例。

 const term = "c" const countries = document.querySelectorAll("#countries div"); for(let i = 0; i < countries.length; i++) { countries[i].innerHTML = countries[i].innerHTML.replace(new RegExp(term, "gi"), (match) => `<mark>${match}</mark>`); }
 <div id="countries"> <div class="item">USA</div> <div class="item">China</div> <div class="item">Canada</div> </div> <div id="output"></div>

I've done something like this:我做了这样的事情:

HTML HTML

<div>
    <form>
      <input type="text" id="input" oninput="filter_list()" placeholder="search..." />
    </form>
   </div>
       <div class="list overflow-auto">
         <ul class="list-group">
            <li class="list-group-item">Elephant</li>
            <li class="list-group-item">Kangaroo</li>
            <li class="list-group-item">Monkey</li>
            <li class="list-group-item">Snake</li>
            <li class="list-group-item">Zebra</li>
            <li class="list-group-item">Panda</li>
         </ul>
       </div>

CSS CSS

.yellow{
  color: #ebae00;
}

JavaScript JavaScript

let input = document.querySelector('#input');
let list = document.querySelector('.list .list-group').querySelectorAll('li');

function filter_list() {
  let result = new RegExp(input.value, 'i');
  list.forEach((item) => {
    if (result.test(item.textContent)) {
      item.innerHTML = item.textContent.replace(result, '<b class="yellow">$&</b>');
      item.style.display = 'block';
    } else {
      item.style.display = 'none';
    }
  });
}

If you want to see the code working, here is my CodePen code: Highlight text filter如果您想查看代码工作,这是我的 CodePen 代码:突出显示文本过滤器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM