如果您添加一些小调整,您可以使用找到的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);
}
这会将所有相邻的 span 与 class highlight 合并(这只是为一般的 highlighter 标签编写的,但可以很容易地使用 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 函数及其遍历整个数组的包装器——小提琴示例中的overdiag)
- 按字符串长度对
words 进行排序,因此最长的字符串会排在最前面
- 突出显示
words 中的所有字符串
- 合并所有相邻的高亮字符串(使用
mergenode函数)
- 最后一组突出显示的字符串保存到
selected1
我今天下午很快把它放在一起,所以这不是这个想法的完美实现,但它有效 =) 我将我的代码添加到荧光笔脚本中,并将它们添加到 jsfiddle 上的一个简单示例中,供您使用 @987654323 @。有一些按钮,因此您可以按下所有不同的步骤并查看它们的作用。