【问题标题】:Get the highlighted text position in .html() and .text()获取 .html() 和 .text() 中突出显示的文本位置
【发布时间】:2013-04-12 18:15:09
【问题描述】:

我正在使用以下脚本来获取突出显示文本的位置:

function getSelectionCharOffsetsWithin(element) {
    var start = 0, end = 0;
    var sel, range, priorRange;
    if (typeof window.getSelection != "undefined") {
        range = window.getSelection().getRangeAt(0);
        priorRange = range.cloneRange();
        priorRange.selectNodeContents(element);
        priorRange.setEnd(range.startContainer, range.startOffset);
        start = priorRange.toString().length;
        end = start + range.toString().length;
    } else if (typeof document.selection != "undefined" &&
        (sel = document.selection).type != "Control") {
        range = sel.createRange();
        priorRange = document.body.createTextRange();
        priorRange.moveToElementText(element);
        priorRange.setEndPoint("EndToStart", range);
        start = priorRange.text.length;
        end = start + range.text.length;
    }
    return {
        start: start,
        end: end
    };
  }

function alertSelection() {
    var mainDiv = document.getElementById("detailBoxParagraph");
    var sel = getSelectionCharOffsetsWithin(mainDiv);
    alert(sel.start + ": " + sel.end);
}

现在,如果我在 $('p').text() 上使用它,它包含

Lorem ipsum dolor sit amet, consetetur sadipscing elitr.

一切正常。但我还需要在 $('p').html() 中获得位置,这显然是不同的,因为<b> 标签

Lorem ipsum dolor `<b>sit</b>` amet, consetetur sadipscing elitr.

如何防止或改变这种情况?

编辑:

我忘了说,我的第一个想法是计算标签出现的次数,然后使用该值来计算新位置,但这有点愚蠢。

我的第二种方法是将标签替换为星号,用于.text()

编辑#2

这是一个显示问题的凌乱小提琴。如果您用鼠标突出显示文本,然后单击该按钮,第一次将正确设置为粗体。第二次无法正常工作。

我会尽快清理小提琴

http://jsfiddle.net/UpLaw/2/

编辑#3

我使用了下面提到的高亮插件,但我无法将功能限制为仅影响标记的字符串。它将突出显示所有匹配的单词或仅突出显示第一个出现的单词。有人可以帮忙吗?

这是必要的代码:

jQuery.fn.highlight = function(pat) {
this.length = 1 ;

function innerHighlight(node, pat) {

    var skip = 0;
    if (node.nodeType == 3) {
        var pos = node.data.toUpperCase().indexOf(pat);
        if (pos >= 0) {
            var spannode = document.createElement('span');
            spannode.className = 'highlight';
            var middlebit = node.splitText(pos);
            var endbit = middlebit.splitText(pat.length);
            var middleclone = middlebit.cloneNode(true);
            spannode.appendChild(middleclone);
            middlebit.parentNode.replaceChild(spannode, middlebit);
            skip = 1;
        }
    }
    else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {

        for (var i = 0; i < 1; ++i) { // So it will highlight only the first occurence. 
            i += innerHighlight(node.childNodes[i], pat);
        }
    }
    return skip;
}
return this.length && pat && pat.length ? this.each(function() {
    innerHighlight(this, pat.toUpperCase());

}) : this;
};

编辑#4

好的,我试着理解那个 javscript。据我所知,这是无法做到的,因为 highlight() 是用一个简单的字符串作为参数调用的。它不能知道这个字符串的位置。我可以/应该解析该位置,然后尝试从该位置搜索,突出显示第一次出现,然后中止吗?

【问题讨论】:

  • 使用预置函数?感觉我在你的问题中遗漏了一些东西......你想要完成什么?
  • 只删除 .html() 包含的所有 HTML 标记是否可以?
  • @ArnelleBalane 这就是 .text 的作用......
  • @Breezer 我试图避免 .html() 中的位置与 .text() 中的位置不同这一事实,因为脚本将标签计为“单词”
  • @ArnelleBalane 不,很遗憾没有

标签: javascript jquery string text


【解决方案1】:

根据您的评论,这就是您想要完成的。

我会尽力解释这一点。英语不是我的母语,所以很抱歉造成混乱。我想在突出显示的文本之前和之后插入一个 html 标记。为此,我必须获取文本的开头和结尾。

假设 sit 是您要处理的突出显示的选择。

您可以使用 .wrap() 或 .after() 和 .before() 来完成此操作。

function alertSelection() {
    $("b", $('#detailBoxParagraph')).wrap('<i/>'); // make the  highlighted section inside a tag.

    $("b", $('#detailBoxParagraph')).before('<u>Content inserted before </u> '); // insert an html before highlighted selections.

    $("b", $('#detailBoxParagraph')).after(' <u>Content inserted after </u>'); // insert an html after highlighted selections.
}

$(function () {
    alertSelection();
})

这里我将突出显示的文本设置为斜体。

查看jsFiddle中的示例

参考


如果你想完成选中的文本高亮,你可以使用jQuery highlight插件。

查看jsFiddle.中的示例

function getSelectionText() {
    var text = "";
    if (window.getSelection) {
        text = window.getSelection().toString();
    } else if (document.selection && document.selection.type != "Control") {
        text = document.selection.createRange().text;
    }
    return text;
}

$(function () {
    $('#detailBoxParagraph').mouseup(function (e){
        $(this).removeHighlight();
        $(this).highlight(getSelectionText());
   });
});

【讨论】:

  • 谢谢,这看起来很不错。但是,叫我笨蛋,这如何适用于突出显示的文本?而且,那个“b”参数是什么?我会先阅读 API。
  • 假设 &lt;b&gt;sit&lt;/b&gt; 是您要处理的突出显示的选择。 $("b", $('#detailBoxParagraph')) 指定您需要选择所有具有粗体标记的元素,该标记位于 ID 为“detailBoxParagraph”的 dom 元素内。换句话说,$('#detailBoxParagraph') 是选择'b'标签的上下文
  • 请看答案中给出的jsFiddle示例。
  • 我猜这里有点理解问题。突出显示,我的意思是用鼠标标记,而不是设置为粗体。我将尝试提供一个显示我的具体问题的小提琴。到目前为止谢谢:)
  • 嗯.. 那里有很多代码.. :) 我认为您可以使用上面给出的高亮插件中使用的相同逻辑。让我再试一次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-07
  • 1970-01-01
  • 2012-07-01
  • 2020-11-09
  • 1970-01-01
  • 2018-08-29
  • 2022-01-23
相关资源
最近更新 更多