更改<mark>标签的背景颜色以模仿CTRL + F功能</mark>

时间:2015-03-24 14:05:28

标签: jquery html css

我试图模仿特定div中浏览器的CTRL + F的功能。首先,用户将输入搜索查询,点击“查找”,&#39;并且所有匹配结果将在div中突出显示。我正在使用以下函数(它完全正常工作)来实现这一目标:

function highlight(str, $elem) {
    var regex = new RegExp(str + "(?!([^<]+)?>)", "gi");
    var found = [];

    $elem.html($elem.html().replace(/<\/?mark>/g, ''));

    if (str === '') return found;

    $elem.html($elem.html().replace(regex, function (matched) {
        found.push(matched);
        return "<mark>" + matched + "</mark>";
    }));

    return found;
}

一旦此函数突出显示所有匹配的结果,我使用以下条件滚动div并在每个结果处停止:

if (found.length > 0) {
    $("#text").scrollTop($("mark:eq(" + searchIndex++ +")").offset().top - $("#text").offset().top + $("#text").scrollTop());
    if (searchIndex === found.length) searchIndex = 0;
}

这也完全符合预期。我遇到麻烦的地方是尝试更改当前&#34; active&#34;的css background-color属性。 &LT;标记&gt;标签。我正在尝试使用类似下面的内容来实现这一目标,但它似乎正在破坏互联网。

if (found.length > 0) {
    $("mark:eq(" + (searchIndex - 1 === -1) ? found.length-1 : searchIndex-1 +")").css({"background-color": "#FFFF00"}) ;
    $("mark:eq(" + searchIndex +")").css({"background-color": "#DAA520"}) ;
    $("#text").scrollTop($("mark:eq(" + searchIndex++ +")").offset().top - $("#text").offset().top + $("#text").scrollTop());
    if (searchIndex === found.length) searchIndex = 0;
}

由于某种原因,这是插入另一个&lt;标记&gt;标记围绕&lt;中的文本h1&gt;我不知道为什么会这样。 jsfiddle的链接如下:

Working search (without background-color changing)

Non-working search (with background-color changing)

1 个答案:

答案 0 :(得分:2)

这是因为您每次单击highlight按钮时都在调用函数find。它必须在第一时间被调用。

var searchIndex = 0;
var first_click = true;
var found;

$("#findField").change(function () {
    searchIndex = 0;
    first_click = true;

    highlight('', $("#text"));  
});

$("#find").click(function () {
    if (first_click) {
        found = highlight(
          $("#findField").val().replace(/\s$/g, ''),
          $("#text")
        );

        first_click = false;
    }

    if (found.length > 0) {
        $("mark:eq(" + ((searchIndex - 1 === -1) ? found.length - 1 : searchIndex - 1) +")").css({"background-color": ""});

        $("#text").scrollTop($("mark:eq(" + searchIndex++ +")").offset().top - $("#text").offset().top + $("#text").scrollTop());

        $("mark:eq(" + ((searchIndex - 1 === -1) ? found.length - 1 : searchIndex - 1) +")").css({"background-color": "#DAA520"});

        if (searchIndex === found.length) searchIndex = 0;
    }
});

$("#findField").mouseup(function () {
    searchIndex = 0;
    this.select();
});

$("#clear").click(function () {
    searchIndex = 0;
    $("#findField").val('');
    highlight('', $("#text"));
});

function highlight(str, $elem) {
    var regex = new RegExp(str + "(?!([^<]+)?>)", "gi");
    var found = [];

    //$elem.html($elem.html().replace(/<\/?mark>/g, ''));

    $elem.find("mark").each(function () {
        $(this).contents().unwrap();
    });

    if (str === '') return found;

    $elem.html($elem.html().replace(regex, function (matched) {
        found.push(matched);
        return "<mark>" + matched + "</mark>";
    }));

    return found;
}

<强> EDITED

所以我将change函数添加到#findField,同时我将此$elem.html($elem.html().replace(/<\/?mark>/g, ''));更改为:

$elem.find("mark").each(function () {
    $(this).contents().unwrap();
});

因为,常规版本与褐色找到的文字(<mark style="background-color: rgb(218, 165, 32);"> ...

不匹配

如果你不理解这个$(this).contents().unwrap();,请在此处查看: Remove a HTML tag but keep the innerHtml

WORKING FIDDLE