繁体   English   中英

如何使用 javascript 突出显示文本

[英]How to highlight text using javascript

有人可以帮助我 javascript function 可以突出显示 web 页面上的文本。 并且要求是 - 只突出显示一次,而不是像我们在搜索时所做的那样突出显示所有出现的文本。

你可以使用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

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

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

你需要做什么:

遍历 HTML 文档,查找所有文本节点,获取textContent ,使用indexOf获取突出显示文本的位置(如果不区分大小写,则使用可选的toLowerCase ),将indexof之前的所有内容附加为textNode ,附加匹配的 Text具有突出显示跨度,并在 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-escape-语句,这样你会找到 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

为什么使用自制的突出显示功能是个坏主意

从头开始构建自己的突出显示功能可能不是一个好主意,因为您肯定会遇到其他人已经解决的问题。 挑战:

  • 您需要删除带有 HTML 元素的文本节点以突出显示您的匹配项,而不会破坏 DOM 事件并一遍又一遍地触发 DOM 重新生成(例如, innerHTML就是这种情况)
  • 如果要删除突出显示的元素,则必须删除 HTML 元素及其内容,并且还必须组合拆分的文本节点以进行进一步搜索。 这是必要的,因为每个荧光笔插件都会在文本节点内搜索匹配项,如果您的关键字将被拆分为多个文本节点,它们将不会被找到。
  • 您还需要构建测试以确保您的插件在您没有考虑过的情况下工作。 我说的是跨浏览器测试!

听起来很复杂? 如果您想要一些功能,例如忽略突出显示中的某些元素、变音符号映射、同义词映射、iframe 内搜索、分隔词搜索等,这将变得越来越复杂。

使用现有插件

使用现有的、良好实现的插件时,您不必担心上述命名的事情。 Sitepoint 上的文章10 jQuery text highlighter plugins比较了流行的荧光笔插件。

看看mark.js

mark.js就是这样一个用纯 JavaScript 编写的插件,但也可以作为 jQuery 插件使用。 它的开发目的是提供比其他插件更多的机会,并提供以下选项:

  • 单独搜索关键字而不是完整的术语
  • 地图变音符号(例如,如果“justo”也应该匹配“justò”)
  • 忽略自定义元素内的匹配项
  • 使用自定义突出显示元素
  • 使用自定义突出显示类
  • 映射自定义同义词
  • 也在 iframe 内搜索
  • 收到未找到的条款

演示

或者你可以看到这个 fiddle

用法示例

// Highlight "keyword" in the specified context
$(".context").mark("keyword");

// Highlight the custom regular expression in the specified context
$(".context").markRegExp(/Lorem/gmi);

它是在 GitHub 上免费开发的开源软件(项目参考)。

function stylizeHighlightedString() {

    var text = window.getSelection();

    // For diagnostics
    var start = text.anchorOffset;
    var end = text.focusOffset - text.anchorOffset;

    range = window.getSelection().getRangeAt(0);

    var selectionContents = range.extractContents();
    var span = document.createElement("span");

    span.appendChild(selectionContents);

    span.style.backgroundColor = "yellow";
    span.style.color = "black";

    range.insertNode(span);
}

这是我的正则表达式纯 JavaScript 解决方案:

function highlight(text) {
    document.body.innerHTML = document.body.innerHTML.replace(
        new RegExp(text + '(?!([^<]+)?<)', 'gi'),
        '<b style="background-color:#ff0;font-size:100%">$&</b>'
    );
}

其他解决方案都不能真正满足我的需求,尽管 Stefan Steiger 的解决方案按我的预期工作,但我发现它有点过于冗长。

以下是我的尝试:

 /** * Highlight keywords inside a DOM element * @param {string} elem Element to search for keywords in * @param {string[]} keywords Keywords to highlight * @param {boolean} caseSensitive Differenciate between capital and lowercase letters * @param {string} cls Class to apply to the highlighted keyword */ function highlight(elem, keywords, caseSensitive = false, cls = 'highlight') { const flags = caseSensitive ? 'gi' : 'g'; // Sort longer matches first to avoid // highlighting keywords within keywords. keywords.sort((a, b) => b.length - a.length); Array.from(elem.childNodes).forEach(child => { const keywordRegex = RegExp(keywords.join('|'), flags); if (child.nodeType !== 3) { // not a text node highlight(child, keywords, caseSensitive, cls); } else if (keywordRegex.test(child.textContent)) { const frag = document.createDocumentFragment(); let lastIdx = 0; child.textContent.replace(keywordRegex, (match, idx) => { const part = document.createTextNode(child.textContent.slice(lastIdx, idx)); const highlighted = document.createElement('span'); highlighted.textContent = match; highlighted.classList.add(cls); frag.appendChild(part); frag.appendChild(highlighted); lastIdx = idx + match.length; }); const end = document.createTextNode(child.textContent.slice(lastIdx)); frag.appendChild(end); child.parentNode.replaceChild(frag, child); } }); } // Highlight all keywords found in the page highlight(document.body, ['lorem', 'amet', 'autem']);
 .highlight { background: lightpink; }
 <p>Hello world lorem ipsum dolor sit amet, consectetur adipisicing elit. Est vel accusantium totam, ipsum delectus et dignissimos mollitia!</p> <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Numquam, corporis. <small>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium autem voluptas perferendis dolores ducimus velit error voluptatem, qui rerum modi?</small> </p>

如果您的关键字可以包含需要在正则表达式中转义的特殊字符,我还建议使用类似escape-string-regexp 的东西:

const keywordRegex = RegExp(keywords.map(escapeRegexp).join('|')), flags);

如果您还希望它在页面加载时突出显示,有一种新方法。

只需添加#:~:text=Highlight%20These

尝试在新选项卡中访问此链接

https://stackoverflow.com/questions/38588721#:~:text=Highlight%20a%20text

突出显示“突出显示文本”文本。

此外,目前仅支持 Chrome(感谢GitGitBoom )。

从 HTML5 开始,您可以使用<mark></mark>标签来突出显示文本。 您可以使用 javascript 在这些标签之间包装一些文本/关键字。 这是一个关于如何标记和取消标记文本的小示例。

JSFIDDLE 演示

我有同样的问题,一堆文本通过 xmlhttp 请求进入。 此文本为 html 格式。 我需要强调每一个事件。

str='<img src="brown fox.jpg" title="The brown fox" />'
    +'<p>some text containing fox.</p>'

问题是我不需要突出显示标签中的文本。 例如我需要突出显示狐狸:

现在我可以将其替换为:

var word="fox";
word="(\\b"+ 
    word.replace(/([{}()[\]\\.?*+^$|=!:~-])/g, "\\$1")
        + "\\b)";
var r = new RegExp(word,"igm");
str.replace(r,"<span class='hl'>$1</span>")

要回答您的问题:您可以在 regexp 选项中省略 g 并且只会替换第一次出现,但这仍然是 img src 属性中的那个并破坏了图像标签:

<img src="brown <span class='hl'>fox</span>.jpg" title="The brown <span 
class='hl'>fox</span> />

这是我解决它的方法,但想知道是否有更好的方法,我在正则表达式中错过了一些东西:

str='<img src="brown fox.jpg" title="The brown fox" />'
    +'<p>some text containing fox.</p>'
var word="fox";
word="(\\b"+ 
    word.replace(/([{}()[\]\\.?*+^$|=!:~-])/g, "\\$1")
    + "\\b)";
var r = new RegExp(word,"igm");
str.replace(/(>[^<]+<)/igm,function(a){
    return a.replace(r,"<span class='hl'>$1</span>");
});

快进到 2019 年,Web API 现在原生支持突出显示文本:

const selection = document.getSelection();
selection.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);

你很高兴去! anchorNode是选择起始节点, focusNode是选择结束节点。 并且,如果它们是文本节点,则offset是各个节点中开始和结束字符的索引。 这是文档

他们甚至有现场演示

简单的 TypeScript 示例

注意:虽然我在很多方面都同意@Stefan,但我只需要一个简单的匹配突出显示:

module myApp.Search {
    'use strict';

    export class Utils {
        private static regexFlags = 'gi';
        private static wrapper = 'mark';

        private static wrap(match: string): string {
            return '<' + Utils.wrapper + '>' + match + '</' + Utils.wrapper + '>';
        }

        static highlightSearchTerm(term: string, searchResult: string): string {
            let regex = new RegExp(term, Utils.regexFlags);

            return searchResult.replace(regex, match => Utils.wrap(match));
        }
    }
}

然后构造实际结果:

module myApp.Search {
    'use strict';

    export class SearchResult {
        id: string;
        title: string;

        constructor(result, term?: string) {
            this.id = result.id;
            this.title = term ? Utils.highlightSearchTerm(term, result.title) : result.title;
        }
    }
}

只需将您的话传递给以下函数

function highlight_words(word) {
    const page = document.body.innerHTML;
    document.body.innerHTML = page.replace(new RegExp(word, "gi"), (match) => `<mark>${match}</mark>`);
}

用法

highlight_words("hello")

这将突出显示页面上该单词的所有实例。

我认为这段代码更好,因为突出显示所有重复的字符

 function highlight(text) { var inputText = document.getElementById("inputText"); var innerHTML = inputText.innerHTML; var index = innerHTML.indexOf(text); if (index >= 0) { inputText.innerHTML=innerHTML.split(text).join('<span class="highlight">'+text+'</span>'); } }
 .highlight { background-color: yellow; }
 <button onclick="highlight('fox')">Highlight</button> <div id="inputText"> The fox went over the fence fox fox fox wen fox </div>

我也想知道,你可以试试我在这篇文章中学到的东西。

我用了:

 function highlightSelection() { var userSelection = window.getSelection(); for(var i = 0; i < userSelection.rangeCount; i++) { highlightRange(userSelection.getRangeAt(i)); } } function highlightRange(range) { var newNode = document.createElement("span"); newNode.setAttribute( "style", "background-color: yellow; display: inline;" ); range.surroundContents(newNode); }
 <html> <body contextmenu="mymenu"> <menu type="context" id="mymenu"> <menuitem label="Highlight Yellow" onclick="highlightSelection()" icon="/images/comment_icon.gif"></menuitem> </menu> <p>this is text, select and right click to high light me! if you can`t see the option, please use this<button onclick="highlightSelection()">button </button><p>

你也可以在这里试试:http: //henriquedonati.com/projects/Extension/extension.html

xc

我想分享更多关于滚动文本片段的使用

语法: #:~:text=[prefix-,]textStart[,textEnd][,-suffix]

如果您想在一个 URL ( &text= ) 中突出显示多个文本片段

例子 演示链接
#:~:text=javascript&text=highlight&text=Ankit 如何使用javascript突出显示文本

查看更多: https ://web.dev/text-fragments/#textstart

关于控制论:谢谢,下面的功能有效。 但是有一个问题,因为它也替换了标签内的单词。 下面是一个示例,如果要突出显示的单词是目标:

<a <mark>target</mark>="_blank" href="Its not OK to highlight <mark>target</mark> here">Its OK to highlight the words <mark>target</mark>s here</a>

我们如何防止这种情况发生?

function highlight_words(word) {
    const page = document.body.innerHTML;
    document.body.innerHTML = page.replace(new RegExp(word, "gi"), (match) => `<mark>${match}</mark>`);
}

我发现高亮插件是最匹配的,它可以突出显示部分内容

$('li')。highlight('bla');

如果您在标记标签内包围任何文本,浏览器将自动以这种醒目的黄色突出显示它。 详细信息可在此处获得: https ://dev.to/comscience/highlight-searched-text-on-a-page-with-just-javascript-17b3

 <h1>
  Searching and Marking
</h1>

<input type="text" id="search"/>
<button onClick="search(id)" id="button">
Highlight
</button>

<p id="text">
What exactly is this Worker thread module, and why do we need it? In this post, we will talk about the historical reasons concurrency is implemented in JavaScript and Node.js, the problems we might find, current solutions, and the future of parallel processing with Worker threads.

Living in a single-threaded world
JavaScript was conceived as a single-threaded programming language that ran in a browser. Being single-threaded means that only one set of instructions is executed at any time in the same process (the browser, in this case, or just the current tab in modern browsers).

This made things easier for implementation and for developers using the language. JavaScript was initially a language only useful for adding some interaction to webpages, form validations, and so on — nothing that required the complexity of multithreading.
</p>

现在 JS 代码看起来像这样

function search(e) {
    let searched = document.getElementById("search").value.trim();
  if (searched !== "") {
    let text = document.getElementById("text").innerHTML;
    let re = new RegExp(searched,"g"); // search for all instances
        let newText = text.replace(re, `<mark>${searched}</mark>`);
        document.getElementById("text").innerHTML = newText;
  }
}

我最近实施了类似的东西。 我的目标是在搜索时实现文本突出显示。 这是我的做法 -

使用接收到的输入创建一个正则表达式。

const regex = new RegExp(`(${value})`, 'gi');

遍历相关元素的元素树。 然后在文本节点中搜索接收到的输入(而不是 innerHTML 以避免属性匹配,例如 class、href 等)。 收到匹配项时。 它(文本节点)与包含所需跨度的包装器跨度交换。 例如。

text ---> <wrapper-span><span> text </span></wrapper-span>

所以,我能够突出显示我的文本。

highlightStr(value, regex, document.getELementById('searchable-div');

const highlightStr = (value, regex, node) => {
        node.childNodes.forEach((childNode) => {
            if (childNode.nodeValue && regex.test(childNode.nodeValue)) {
                const highLightWrapper = document.createElement('span');
                highLightWrapper.classList.add("highlight-wrapper-class");

                childNode.replaceWith(highLightedWrapper);

                highLightWrapper.innerHTML = childNode.nodeValue.replace(regex, `<span class="highlight">${value}</span>`);
            }
            this.highlightStr(value, regex, childNode);
        });
    }

但现在的问题是,如果我们在尝试再次突出显示文本之前不删除(或检查现有的)wrapper-span 结构。 我们可能会以无限包装跨度树或失败的搜索结束。 所以我为它实现了一个reset function。 您可能希望每次要突出显示文本时都运行它。 它基本上只是用文本内容换回文本节点。 所以我们在突出显示文本之前得到了我们所拥有的。

resetHighlight(document.getELementById('searchable-div');

const resetHighlight = (node) => {
        node.childNodes.forEach((childNode) => {
            if ((childNode as HTMLElement).classList && (childNode as HTMLElement).classList.contains('highlight-wrapper-class') && childNode.textContent) {
                childNode.replaceWith(childNode.textContent);
            }
            this.resetHighlight(childNode);
        });
    }

Range类型上使用roundContents()方法。 它唯一的参数是将包装该范围的元素。

function styleSelected() {
  bg = document.createElement("span");
  bg.style.backgroundColor = "yellow";
  window.getSelection().getRangeAt(0).surroundContents(bg);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM