我正在寻找一个元素中多个突出显示文本的jquery插件。我发现了一个非常受欢迎的插件:http://bartaz.github.com/sandbox.js/jquery.highlight.html以及其他许多插件。
它们工作正常,但如果我想突出显示与之前突出显示的文本重叠的文本 - 它不起作用。
有没有人知道jquery或javascript插件支持多个突出显示的文本并正确突出显示重叠的文本?
答案 0 :(得分:15)
如果添加一些小调整,您可以使用找到的highlighter plugin执行所有操作。 作为一个例子,我发布了一个工作示例,我今天下午快速整理了这个例子:http://jsfiddle.net/4bwgA/
在这里,我将逐步介绍插件(OP引用的)已经完成的所有事情,并在最后给出重叠突出显示区域的解决方案。
荧光笔的作用是在你应用它的单词周围加上标记。所以,如果你有
<p>Who is the quick brown fox?</p>
你用
突出显示了“棕色”这个词 $("p").highlight("brown");
你得到了
<p>Who is the quick <span class="highlight">brown</span> fox?</p>
和另一个命令
$("p").highlight("brown fox");
找不到任何东西, 因为字符串不再有这个子字符串,因为它现在有棕色的标签。
因此,如果只是重叠...解决方案很容易。该软件包提供了一个非突出显示功能,您可以在新的突出显示之前应用
$("p").unhighlight().highlight("brown fox");
并获取
<p>Who is the quick <span class="highlight">brown fox</span>?</p>
到目前为止,这并不令人兴奋。但是,如果我们一次性突出显示“棕色”,然后在下一个突出显示“狐狸”,那该怎么办?我们得到了这个
<p>Who is the quick <span class="highlight">brown</span> <span class="highlight">fox</span>?</p>
然后我们想加入邻近突出显示的区域。这可以通过一个附加功能来完成,它可以做到这样:
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的两个额外参数轻松扩展,用于自定义标记)。结果将如下所示
<p>Who is the quick <span class="highlight">brown fox</span>?</p>
到目前为止一切顺利。但是如果我们的搜索字符串重叠怎么办?
首先......重叠的最佳方法是在检查已清除文本上的重叠字符串之前取消选择旧选择。为此,我们需要记住之前的选择,例如可以保存在一个数组中(我称之为selected1
),它在每次额外选择时都会获得一个值。
在每次运行时,最终选择(全部合并)都保存到selected1
数组中,以便它可以用于将来的合并和重叠。
现在,荧光笔如何处理字符串数组?它按照传递给函数的顺序对每个函数应用高亮函数。因此,如果两个字符串完全重叠,我们可以通过对选择字符串数组进行排序并首先突出显示较长字符串来处理它。例如
$("p").highlight(["brown fox","brown"]);
只会突出显示
<p>Who is the quick <span class="highlight">brown fox</span>?</p>
可以使用类似的
按长度对数组进行排序 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
数组中,其中所有可能的重叠字符串已连接在一起。
所以现在我们拥有了我们需要的所有部件,我们可以将它们组合在一起。每次我们想要突出显示新的字符串或字符串数组时,我们都会执行以下步骤:
selected1
数组中)。words
数组selected1
附加到words
words
中所有部分重叠的字符串对,并将新的组合字符串添加到words
(使用overlap
函数及其遍历整个数组的包装器 - {{1在小提琴例子中)overdiag
,因此最长的字符串将首先出现words
words
功能)mergenode
我今天下午快速把它放在一起,所以这不是一个完美的想法实现,但它的工作原理=)我将我的代码添加到荧光笔脚本中并将它们添加到jsfiddle上的一个简单示例中供您使用{{ 3}}。有按钮,您可以按下所有不同的步骤,看看他们做了什么。