在 Firefox 中缓慢突出显示

2022-01-24 00:00:00 range firefox javascript html highlighting

We need to add anchors and highlights for some keywords/sentences in the html page. It turns out the highlighting is really slow in Firefox.

In the following code, all ranges which need to be highlighted are stored in array hiliteRanges:

for (var i = 0; i < hiliteRanges.length; i++){
    document.designMode = "on";

    var selHilites = window.getSelection();

    if (selHilites.rangeCount > 0)
        selHilites.removeAllRanges();

    selHilites.addRange(hiliteRanges[i]);

    var anchorId = 'index'+i;
    var insertedHTML = '<span id="' + anchorId + '" style="background-color: #FF8C00;" >'+hiliteRanges[i].toString()+'</span>';

    document.execCommand('inserthtml', false, insertedHTML);                                                                                    
    document.designMode = "off";
}

Is there any way to speed up the processing? We could have hundreds of ranges in the array hiliteRanges. We once tried moving the designMode setting outside of the loop, but we can see some sections are editable in the html page when the loop is running.

解决方案

There's no need to use document.execCommand() for this. Just use range methods instead, and then there's no need for designMode.

var anchorId, hiliteTextNode, hiliteSpan;
for (var i = 0; i < hiliteRanges.length; i++){
    // Create the highlight element
    hiliteSpan = document.createElement("span");
    hiliteSpan.id = anchorId;
    hiliteSpan.style.backgroundColor = "#FF8C00";

    hiliteTextNode = document.createTextNode(hiliteRanges[i].toString());
    hiliteSpan.appendChild(hiliteTextNode);

    // Replace the range content
    hiliteRanges[i].deleteContents();
    hiliteRanges[i].insertNode(hiliteSpan);
}

Also, since ranges are affected by DOM mutation, I would suggest doing this part at the same time as you collect the ranges with window.find(). Here's an example:

http://jsfiddle.net/YgFjT/

相关文章