用于突出显示文本的JQuery / JavaScript插件

我正在为元素中的多个突出显示的文本寻找一个jquery插件。 我找到了一个非常受欢迎的插件: http : //bartaz.github.com/sandbox.js/jquery.highlight.html以及其他许多插件。

它们工作正常,但如果我想突出显示与早期突出显示的文本重叠的文本 – 它不起作用。

有没有人知道jquery或javascript插件支持多个突出显示的文本,并正确突出重叠的文本?

如果你添加一些小调整,你可以使用你找到的荧光笔插件做任何事情。 作为一个例子,我发布了一个工作示例,我今天下午快速整理了一起: http : //jsfiddle.net/4bwgA/

在这里,我将逐步介绍插件(OP引用)已经完成的所有事情,并在最后给出重叠突出显示区域的解决方案。

荧光笔的作用是在您应用它的单词周围添加标签。 所以,如果你有

Who is the quick brown fox?

你突出了“棕色”这个词

  $("p").highlight("brown"); 

你得到

  

Who is the quick brown fox?

还有一个额外的命令

  $("p").highlight("brown fox"); 

将找不到任何东西,因为字符串不再有这个子字符串,因为它现在有褐色的标签。

因此,如果只是重叠…解决方案很容易。 该软件包提供了一种不亮的function,您可以在新的高亮显示之前应用

  $("p").unhighlight().highlight("brown fox"); 

得到

  

Who is the quick brown fox?

到目前为止,这并不令人兴奋。 但是,如果我们一次性突出显示“棕色”,然后在下一个突出显示“狐狸”,那该怎么办? 我们明白了

  

Who is the quick brown fox?

然后我们想加入邻近突出显示的区域。 这可以通过一个附加function来完成,它可以做到这样的事情:

  function mergenode(node) { var parent1 = node.contents(); parent1.each(function (i) { if (i > 0 && this.nodeType !== 1 && //if text node this.data.search(/^\s*$/g) === 0 && //consisting only of hyphens or blanks parent1[i - 1].nodeName === "SPAN" && //bordering to SPAN elements parent1[i + 1].nodeName === "SPAN" && parent1[i - 1].className === "highlight" && //of class highlight parent1[i + 1].className === "highlight") { selected1.push(parent1[i - 1] .textContent.concat(this.data, parent1[i + 1].textContent)); } else if (this.nodeType === 1 && this.nodeName === "SPAN" && parent1[i + 1].nodeName === "SPAN" && this.className === "highlight" && parent1[i + 1].className === "highlight") { selected1.push(this.textContent.concat(parent1[i + 1].textContent)); } }); $(node).unhighlight().highlight(selected1); } 

这将合并所有相邻的跨度与类高亮(这只是为一般的荧光笔标记编写,但可以很容易地扩展为nodeName和className的两个额外参数,用于自定义标记)。 结果将如下所示

  

Who is the quick brown fox?

到目前为止都很好。 但是如果我们的搜索字符串重叠怎么办? 首先……与重叠相关的最好的事情是在检查已清除文本上的重叠字符串之前取消选择旧选择。 为此我们需要记住之前的选择,例如可以保存在一个数组中(我称之为selected1 ),它在每个附加选择时都会获得一个值。

在每次运行时,最终选择(全部合并)都保存到selected1数组中,以便它可以用于将来的合并和重叠。

现在,荧光笔如何处理字符串数组? 它按照它们传递给函数的顺序对每个函数应用高亮函数。 因此,如果两个字符串完全重叠,我们可以通过对选择字符串数组进行排序并首先突出显示较长的字符串来处理它。 例如

  $("p").highlight(["brown fox","brown"]); 

只会突出显示

  

Who is the quick brown fox?

可以按照这样的长度对数组进行排序

  words = words.sort(function (str1, str2) { return (str1.length < str2.length) ? 1 : 0; }); 

现在处理完全重叠和相邻的亮点。 现在我们必须确保我们得到部分重叠的字符串。 在这里我编写了一个比较两个字符串重叠的函数...还有其他方法可以做到这一点,但我想在这个答案中展示的主要是你需要做的一系列步骤,以突出你的方式想=)

此函数接受两个字符串,检查它们是否重叠,如果是,则组合它们并将新的组合字符串保存到数组中, toselect ,最后将其附加到原始words数组。 可能会有一些无用的组合,但它不会受到伤害 - 它们最终不会显示出来。

  function overlap(a, b) { var l = b.length, m = a.length; for (var j = 1; j < l; j++) { if (a.indexOf(b.substr(l - j)) === 0) { toselect.push(b.concat(a.substr(j))); } else if (a.substr(m - j).indexOf(b.substr(0, j)) === 0) { toselect.push(a.concat(b.substr(j))); } } } 

现在我们要将此函数应用于words数组中所有可能的元素对。 我们可以循环迭代这个,但我有点兴奋并做到了这一点

  $.each(arr, function (i) { $.each(arr.slice(i + 1), function (i, v) { overlap(arr[i], v); }); }); 

现在我们只需将新的toselect数组附加到原始的words数组中,其中所有可能的重叠字符串已连接在一起。

所以现在我们拥有了我们需要的所有部件,我们可以将它们组合在一起。 每次我们想要突出显示新字符串或字符串数​​组时,我们都会执行以下步骤:

  1. 取消高亮显示当前突出显示的所有内容(突出显示的任何内容都将位于selected1数组中)。
  2. 我们的新字符串或字符串数​​组进入words数组
  3. selected1附加到words
  4. words组合所有部分重叠的字符串对,并将新的组合字符串添加到words (使用overlap函数及其遍历整个数组的包装器 - 在小提琴示例中使用overdiag)
  5. 按字符串长度对words进行排序,因此最长的字符串将首先出现
  6. 突出显示words所有字符串
  7. 合并所有相邻的突出显示的字符串(使用mergenode函数)
  8. 最后一组突出显示的字符串将保存到selected1

我今天下午快速把它放在一起,所以这不是一个完美的想法实现,但它的工作原理=)我将我的代码添加到荧光笔脚本中并将它们添加到jsfiddle上的一个简单示例中,以便您使用http:// jsfiddle .net / 4bwgA / 。 有按钮,您可以按下所有不同的步骤,看看他们做了什么。