如何使用javascript突出显示文本

新手上路,请多包涵

有人可以帮助我使用可以突出显示网页上文本的 javascript 函数。

并且要求是 - 仅突出显示一次,而不是像我们在搜索时那样突出显示所有出现的文本。

原文由 Ankit 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

你可以使用jquery 高亮效果

但是如果你对原始的 javascript 代码感兴趣,看看我得到了什么

只需将粘贴复制到 HTML 中,打开文件并单击“突出显示” - 这应该突出显示“狐狸”一词。性能方面,我认为这适用于小文本和单次重复(如您指定)

 function highlight(text) {
 var inputText = document.getElementById("inputText");
 var innerHTML = inputText.innerHTML;
 var index = innerHTML.indexOf(text);
 if (index >= 0) {
 innerHTML = innerHTML.substring(0,index) + "<span class='highlight'>" + innerHTML.substring(index,index+text.length) + "</span>" + innerHTML.substring(index + text.length);
 inputText.innerHTML = innerHTML;
 }
 }
 .highlight {
 background-color: yellow;
 }
 <button onclick="highlight('fox')">Highlight</button>

 <div id="inputText">
 The fox went over the fence
 </div>

编辑:

使用 replace

我看到这个答案获得了一些人气,我想我可以补充一下。

您还可以轻松地使用替换

"the fox jumped over the fence".replace(/fox/,"<span>fox</span>");

或者对于多次出现(与问题无关,但在评论中被问到),您只需在替换正则表达式上添加 global

"the fox jumped over the other fox".replace(/fox/g,"<span>fox</span>");

希望这对感兴趣的评论者有所帮助。

将 HTML 替换为整个网页

要替换整个网页的 HTML,您应该参考文档正文的 innerHTML

document.body.innerHTML

原文由 guy mograbi 发布,翻译遵循 CC BY-SA 3.0 许可协议

这里提供的解决方案非常糟糕。

  1. 你不能使用正则表达式,因为那样的话,你会在 html 标签中搜索/突出显示。
  2. 您不能使用正则表达式,因为它不能与 UTF*(任何非拉丁/英文字符)一起正常工作。
  3. 你不能只做一个 innerHTML.replace,因为当字符有一个特殊的 HTML 符号时,这不起作用,例如 &amp; 对于 &, &lt; 对于 <, &gt; for >, &auml; for ä, &ouml; for ö &uuml; for ü &szlig; for ß, etc.

你需要做什么:

遍历 HTML 文档,找到所有文本节点,获取 textContent ,使用 indexOf 获取高亮文本的位置(可选 toLowerCase -faf24应该不区分大小写),在 indexof 之前追加所有内容作为 textNode ,追加带有高亮范围的匹配文本,并重复文本节点的其余部分(高亮字符串可能出现多个 textContent 字符串中的时间)。

这是为此的代码:

 var InstantSearch = {

    "highlight": function (container, highlightText)
    {
        var internalHighlighter = function (options)
        {

            var id = {
                container: "container",
                tokens: "tokens",
                all: "all",
                token: "token",
                className: "className",
                sensitiveSearch: "sensitiveSearch"
            },
            tokens = options[id.tokens],
            allClassName = options[id.all][id.className],
            allSensitiveSearch = options[id.all][id.sensitiveSearch];

            function checkAndReplace(node, tokenArr, classNameAll, sensitiveSearchAll)
            {
                var nodeVal = node.nodeValue, parentNode = node.parentNode,
                    i, j, curToken, myToken, myClassName, mySensitiveSearch,
                    finalClassName, finalSensitiveSearch,
                    foundIndex, begin, matched, end,
                    textNode, span, isFirst;

                for (i = 0, j = tokenArr.length; i < j; i++)
                {
                    curToken = tokenArr[i];
                    myToken = curToken[id.token];
                    myClassName = curToken[id.className];
                    mySensitiveSearch = curToken[id.sensitiveSearch];

                    finalClassName = (classNameAll ? myClassName + " " + classNameAll : myClassName);

                    finalSensitiveSearch = (typeof sensitiveSearchAll !== "undefined" ? sensitiveSearchAll : mySensitiveSearch);

                    isFirst = true;
                    while (true)
                    {
                        if (finalSensitiveSearch)
                            foundIndex = nodeVal.indexOf(myToken);
                        else
                            foundIndex = nodeVal.toLowerCase().indexOf(myToken.toLowerCase());

                        if (foundIndex < 0)
                        {
                            if (isFirst)
                                break;

                            if (nodeVal)
                            {
                                textNode = document.createTextNode(nodeVal);
                                parentNode.insertBefore(textNode, node);
                            } // End if (nodeVal)

                            parentNode.removeChild(node);
                            break;
                        } // End if (foundIndex < 0)

                        isFirst = false;

                        begin = nodeVal.substring(0, foundIndex);
                        matched = nodeVal.substr(foundIndex, myToken.length);

                        if (begin)
                        {
                            textNode = document.createTextNode(begin);
                            parentNode.insertBefore(textNode, node);
                        } // End if (begin)

                        span = document.createElement("span");
                        span.className += finalClassName;
                        span.appendChild(document.createTextNode(matched));
                        parentNode.insertBefore(span, node);

                        nodeVal = nodeVal.substring(foundIndex + myToken.length);
                    } // Whend

                } // Next i
            }; // End Function checkAndReplace

            function iterator(p)
            {
                if (p === null) return;

                var children = Array.prototype.slice.call(p.childNodes), i, cur;

                if (children.length)
                {
                    for (i = 0; i < children.length; i++)
                    {
                        cur = children[i];
                        if (cur.nodeType === 3)
                        {
                            checkAndReplace(cur, tokens, allClassName, allSensitiveSearch);
                        }
                        else if (cur.nodeType === 1)
                        {
                            iterator(cur);
                        }
                    }
                }
            }; // End Function iterator

            iterator(options[id.container]);
        } // End Function highlighter
        ;

        internalHighlighter(
            {
                container: container
                , all:
                    {
                        className: "highlighter"
                    }
                , tokens: [
                    {
                        token: highlightText
                        , className: "highlight"
                        , sensitiveSearch: false
                    }
                ]
            }
        ); // End Call internalHighlighter

    } // End Function highlight

};

然后你可以像这样使用它:

 function TestTextHighlighting(highlightText)
{
    var container = document.getElementById("testDocument");
    InstantSearch.highlight(container, highlightText);
}

这是一个示例 HTML 文档

<!DOCTYPE html>
<html>
    <head>
        <title>Example of Text Highlight</title>
        <style type="text/css" media="screen">
            .highlight{ background: #D3E18A;}
            .light{ background-color: yellow;}
        </style>
    </head>
    <body>
        <div id="testDocument">
            This is a test
            <span> This is another test</span>
            äöüÄÖÜäöüÄÖÜ
            <span>Test123&auml;&ouml;&uuml;&Auml;&Ouml;&Uuml;</span>
        </div>
    </body>
</html>

顺便说一句,如果您在数据库中搜索 LIKE

例如 WHERE textField LIKE CONCAT('%', @query, '%') [你不应该这样做,你应该使用全文搜索或Lucene],然后你可以用\转义每个字符并添加一个SQL转义语句,这样你会发现特别作为 LIKE 表达式的字符。

例如

WHERE textField LIKE CONCAT('%', @query, '%') ESCAPE '\'

@query 的值不是 '%completed%' 而是 '%\c\o\m\p\l\e\t\e\d%'

(经过测试,适用于 SQL-Server 和 PostgreSQL,以及支持 ESCAPE 的所有其他 RDBMS 系统)


修改后的打字稿版本:

 namespace SearchTools
{

    export interface IToken
    {
        token: string;
        className: string;
        sensitiveSearch: boolean;
    }

    export class InstantSearch
    {

        protected m_container: Node;
        protected m_defaultClassName: string;
        protected m_defaultCaseSensitivity: boolean;
        protected m_highlightTokens: IToken[];

        constructor(container: Node, tokens: IToken[], defaultClassName?: string, defaultCaseSensitivity?: boolean)
        {
            this.iterator = this.iterator.bind(this);
            this.checkAndReplace = this.checkAndReplace.bind(this);
            this.highlight = this.highlight.bind(this);
            this.highlightNode = this.highlightNode.bind(this);

            this.m_container = container;
            this.m_defaultClassName = defaultClassName || "highlight";
            this.m_defaultCaseSensitivity = defaultCaseSensitivity || false;
            this.m_highlightTokens = tokens || [{
                token: "test",
                className: this.m_defaultClassName,
                sensitiveSearch: this.m_defaultCaseSensitivity
            }];
        }

        protected checkAndReplace(node: Node)
        {
            let nodeVal: string = node.nodeValue;
            let parentNode: Node = node.parentNode;
            let textNode: Text = null;

            for (let i = 0, j = this.m_highlightTokens.length; i < j; i++)
            {
                let curToken: IToken = this.m_highlightTokens[i];
                let textToHighlight: string = curToken.token;
                let highlightClassName: string = curToken.className || this.m_defaultClassName;
                let caseSensitive: boolean = curToken.sensitiveSearch || this.m_defaultCaseSensitivity;

                let isFirst: boolean = true;
                while (true)
                {
                    let foundIndex: number = caseSensitive ?
                        nodeVal.indexOf(textToHighlight)
                        : nodeVal.toLowerCase().indexOf(textToHighlight.toLowerCase());

                    if (foundIndex < 0)
                    {
                        if (isFirst)
                            break;

                        if (nodeVal)
                        {
                            textNode = document.createTextNode(nodeVal);
                            parentNode.insertBefore(textNode, node);
                        } // End if (nodeVal)

                        parentNode.removeChild(node);
                        break;
                    } // End if (foundIndex < 0)

                    isFirst = false;

                    let begin: string = nodeVal.substring(0, foundIndex);
                    let matched: string = nodeVal.substr(foundIndex, textToHighlight.length);

                    if (begin)
                    {
                        textNode = document.createTextNode(begin);
                        parentNode.insertBefore(textNode, node);
                    } // End if (begin)

                    let span: HTMLSpanElement = document.createElement("span");

                    if (!span.classList.contains(highlightClassName))
                        span.classList.add(highlightClassName);

                    span.appendChild(document.createTextNode(matched));
                    parentNode.insertBefore(span, node);

                    nodeVal = nodeVal.substring(foundIndex + textToHighlight.length);
                } // Whend

            } // Next i

        } // End Sub checkAndReplace

        protected iterator(p: Node)
        {
            if (p == null)
                return;

            let children: Node[] = Array.prototype.slice.call(p.childNodes);

            if (children.length)
            {
                for (let i = 0; i < children.length; i++)
                {
                    let cur: Node = children[i];

                    // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
                    if (cur.nodeType === Node.TEXT_NODE)
                    {
                        this.checkAndReplace(cur);
                    }
                    else if (cur.nodeType === Node.ELEMENT_NODE)
                    {
                        this.iterator(cur);
                    }
                } // Next i

            } // End if (children.length)

        } // End Sub iterator

        public highlightNode(n:Node)
        {
            this.iterator(n);
        } // End Sub highlight

        public highlight()
        {
            this.iterator(this.m_container);
        } // End Sub highlight

    } // End Class InstantSearch

} // End Namespace SearchTools

用法:

 let searchText = document.getElementById("txtSearchText");
let searchContainer = document.body; // document.getElementById("someTable");
let highlighter = new SearchTools.InstantSearch(searchContainer, [
    {
        token: "this is the text to highlight" // searchText.value,
        className: "highlight", // this is the individual highlight class
        sensitiveSearch: false
    }
]);

// highlighter.highlight(); // this would highlight in the entire table
// foreach tr - for each td2
highlighter.highlightNode(td2); // this highlights in the second column of table

原文由 Stefan Steiger 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题