获取选择&跨多个标签环绕内容

发布于 2024-08-28 00:36:49 字数 538 浏览 6 评论 0原文

我有一个脚本可以更改所选文本的背景颜色。但是,当跨多个元素/标签选择文本时,我遇到了问题。

我得到的代码是:

var text = window.getSelection().getRangeAt(0);
var colour = document.createElement("hlight");
colour.style.backgroundColor = "Yellow";
text.surroundContents(colour);

输出的错误是:

Error: The boundary-points of a range does not meet specific requirements. =
NS_ERROR_DOM_RANGE_BAD_BOUNDARYPOINTS_ERR
Line: 7

我相信这与 getRange() 函数有关,尽管我不太确定如何继续,因为我是 javascript 的初学者。

还有其他方法可以复制我想要实现的目标吗?

非常感谢。

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/tags.

The code that i've got is:

var text = window.getSelection().getRangeAt(0);
var colour = document.createElement("hlight");
colour.style.backgroundColor = "Yellow";
text.surroundContents(colour);

And the error being output is:

Error: The boundary-points of a range does not meet specific requirements. =
NS_ERROR_DOM_RANGE_BAD_BOUNDARYPOINTS_ERR
Line: 7

I believe this is to do with the getRange() function though i'm not too sure how to proceed since I am a beginner at javascript.

Is there any other way I can replicate what I am trying to achieve?

Many thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

Saygoodbye 2024-09-04 00:36:49

今天有人问这个问题: 如何突出显示 DOM 的文本Range 对象?

这是我的答案:

以下应该执行您想要的操作。在非 IE 浏览器中,它会打开设计模式,应用背景颜色,然后再次关闭设计模式。

更新

已修复以在 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);
    }
}

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);
    }
}
谁人与我共长歌 2024-09-04 00:36:49

好吧,我认为在这种情况下使用 mark.js 库非常好。该库的目的是突出显示 HTML 文档中某个单词的所有实例,但可以通过 filter 选项功能对其进行调整,并且可以通过 each 添加其他 span 属性强>选项功能。

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;
        }
  });
};

检查此 JSFiddle 示例,以获取突出显示用户选择的完整代码,甚至跨多个 HTML 元素也是如此。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文