突出显示HTML页面中的重复单词

时间:2019-06-11 18:09:43

标签: javascript jquery html css vue.js

我有一个包含 v-html 结果的表(因此,在呈现页面之前,表中的文本将不存在)。我想比较两行,如果它们有重复的单词,则应突出显示它们。

这里是我想要的example project,但远远超出了我需要的范围。我的问题似乎最像this one in the stacks,但它要求定义单词,我希望页面能够找到它们本身。

例如,这将是预期的输出:

<table>
  <tr>
    <td v-html="link.orderdesciption">
    order:<br />
   <mark> TV </mark><br /> <!--note that the contents of the td would not appear in markup due to being v-html-->
    PS3 <br />
    Laptop
    </td>
    <td>
    qty:<br />
    1<br />
    2<br />
    1<br />
    </td>
  </tr>
  <tr>
    <td>
    ----------------
    </td>
    <td>
    ----------------
    </td>
  </tr>
  <tr>
    <td v-html="link.orderrecieved">
    recieved:<br /> <!--same note as above, v-html only shows-->
    <mark> TV </mark><br />
    Desktop<br />
    </td>
  </tr>
</table>

我一直在努力,但是我真的不知道从这里去哪里

var text = $('td').text(),
    words = text.split(' '),
    sortedWords = words.slice(0).sort(),
    duplicateWords = [];


for (var i=0; i<sortedWords.length-1; i++) {
    if (sortedWords[i+1] == sortedWords[i]) {
        duplicateWords.push(sortedWords[i]);
    }
}
duplicateWords = $.unique(duplicateWords);

感谢您的建议

2 个答案:

答案 0 :(得分:0)

使用reduce获取duplicate words,然后可以遍历tds来检查其中的文本 在重复单词Array中。如果是,则将文本包装在mark标记中。

const tds = document.querySelectorAll('td');

const groupByOccurence = [...tds].reduce((accu, td) => {
  const textArr = td.innerHTML.split('<br>').map((word) => word.trim()).filter((word) => word.length > 0 && word.match(/[a-zA-Z]+/g));
  textArr.forEach((text) => {
    accu[text] = (accu[text] || 0) + 1;
  });
  return accu;
}, {});

const duplicateWords = Object.entries(groupByOccurence).filter(([_, val]) => val > 1).map(([key, _]) => key);

tds.forEach((td) => {
  const textArr = td.innerHTML.split('<br>').map((word) => word.trim());
  let str = "";
  textArr.forEach((text) => {
    if (duplicateWords.includes(text)) {
      str += '<mark>' + text + '</mark><br>';
    } else {
      str += text + '<br>';
    }
    td.innerHTML = str;
  })
});

const trs = document.querySelectorAll('tr');

trs.forEach((tr, i) => {
  const specialChartds = [...tr.querySelectorAll('td')].filter((td) => !td.textContent.match(/[a-zA-Z]+/g));
  if (!specialChartds) {
    tr.append(tds[i]);
  }
});
<table>
  <tr>
    <td>
      order:<br /> TV
      <br /> PS3 <br /> Laptop
    </td>
    <td>
      qty:<br /> 1
      <br /> 2
      <br /> 1
      <br />
    </td>
  </tr>
  <tr>
    <td>
      ----------------
    </td>
    <td>
      ----------------
    </td>
  </tr>
  <tr>
    <td>
      recieved:<br /> TV <br /> Desktop
      <br />
    </td>
  </tr>
</table>

答案 1 :(得分:0)

要获得预期结果,请使用以下选项

  1. 通过在每个循环$('table')来从表中获取所有单词
  2. 使用过滤器方法创建来自step1的所有重复单词的数组
  3. 对所有tds进行循环,并为重复的单词添加标记标签

var text = $('table');
var arr = [];

//Step 1: Getting All words from table
var words = text.each(function(){
   let val = $(this).text().replace(/\n|\r/g,' ').split(' ').filter(Boolean);
   arr.push(...val)
})


//Step 2: Finding duplicate words
let duplicate = arr.filter(function(value,index,self){ return (self.indexOf(value) !== index && isNaN(parseInt(value)) && value.match(/[A-Za-z]/) !== null)})


//Step 3: Marking duplicate words in each row
$('td').each(function(){
   let val = $(this).text();
   let openMark = '<mark>'
   let closeMark = '</mark>'
   duplicate.forEach(v => {
      if(val.indexOf(v) !== -1){
          var html = $(this).html().replace(v, openMark + v + closeMark)
          $(this).html(html)
      }
   })
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td>
    order:<br />
   TV<br />
    PS3 <br />
    Laptop
    </td>
    <td>
    qty:<br />
    1<br />
    2<br />
    1<br />
    </td>
  </tr>
  <tr>
    <td>
    ----------------
    </td>
    <td>
    ----------------
    </td>
  </tr>
  <tr>
    <td>
    recieved:<br />
    TV<br />
    Desktop<br />
    </td>
  </tr>
</table>

codepen-https://codepen.io/nagasai/pen/YoPPMv?editors=1010