getSelection & surroundContents across multiple tags

前端 未结 2 589
予麋鹿
予麋鹿 2020-12-01 07:13

I\'ve got a script that changes the background colour of text that has been selected. However i\'m encountering an issue when the text is selected across multiple elements/t

相关标签:
2条回答
  • 2020-12-01 07:27

    This question has been asked today: How can I highlight the text of the DOM Range object?

    Here's my answer:

    The following should do what you want. In non-IE browsers it turns on designMode, applies a background colour and then switches designMode off again.

    UPDATE

    Fixed to work in IE 9.

    function makeEditableAndHighlight(colour) {
        sel = window.getSelection();
        if (sel.rangeCount && sel.getRangeAt) {
            range = sel.getRangeAt(0);
        }
        document.designMode = "on";
        if (range) {
            sel.removeAllRanges();
            sel.addRange(range);
        }
        // Use HiliteColor since some browsers apply BackColor to the whole block
        if (!document.execCommand("HiliteColor", false, colour)) {
            document.execCommand("BackColor", false, colour);
        }
        document.designMode = "off";
    }
    
    function highlight(colour) {
        var range, sel;
        if (window.getSelection) {
            // IE9 and non-IE
            try {
                if (!document.execCommand("BackColor", false, colour)) {
                    makeEditableAndHighlight(colour);
                }
            } catch (ex) {
                makeEditableAndHighlight(colour)
            }
        } else if (document.selection && document.selection.createRange) {
            // IE <= 8 case
            range = document.selection.createRange();
            range.execCommand("BackColor", false, colour);
        }
    }
    
    0 讨论(0)
  • 2020-12-01 07:38

    Well I think the use of mark.js library is great in this case. The library's intention is to highlight all instances of a certain word in the HTML document, but it can be tweaked through the filter option function, and additional span attributes can be added through the each option function.

    function markFunc(node, text, color) {
      var instance = new Mark(node);
        instance.mark(text, {
        "element": "span",
          "className": color,
          "acrossElements": true,
          "separateWordSearch": false,
          "accuracy": "partially",
          "diacritics": true,
          "ignoreJoiners": true,
        "each": function(element) {
                element.setAttribute("id", "sohayb");
                element.setAttribute("title", "sohayb_title");
           },
        "done":function(totalMarks) {
                window.getSelection().empty();//This only in Chrome
                console.log("total marks: " + totalMarks);
         },
          "filter": function(node, term, totalCounter, counter) {
            var res = false;
            if (counter == 0) {
                res = selectionRange.isPointInRange(node, selectionRange.startOffset);
            } else {
            res = selectionRange.isPointInRange(node, 1);
            }
            console.log("Counter: " + counter + ", startOffset: " + selectionRange.startOffset);
            return res;
            }
      });
    };
    

    Check this JSFiddle sample for completed code that highlights user's selection, even across multiple HTML elements.

    0 讨论(0)
提交回复
热议问题