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

时间:2012-08-18 11:30:54

标签: javascript jquery

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

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

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

1 个答案:

答案 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数组中,其中所有可能的重叠字符串已连接在一起。

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

  1. 取消高亮显示当前突出显示的所有内容(突出显示的任何内容都位于selected1数组中)。
  2. 我们的新字符串或字符串数​​组会进入words数组
  3. selected1附加到words
  4. 合并words中所有部分重叠的字符串对,并将新的组合字符串添加到words(使用overlap函数及其遍历整个数组的包装器 - {{1在小提琴例子中)
  5. 按字符串长度排序overdiag,因此最长的字符串将首先出现
  6. 突出显示words
  7. 中的所有字符串
  8. 合并所有相邻的突出显示的字符串(使用words功能)
  9. 最后一组突出显示的字符串保存在mergenode
  10. 我今天下午快速把它放在一起,所以这不是一个完美的想法实现,但它的工作原理=)我将我的代码添加到荧光笔脚本中并将它们添加到jsfiddle上的一个简单示例中供您使用{{ 3}}。有按钮,您可以按下所有不同的步骤,看看他们做了什么。