当前位置:  开发笔记 > 编程语言 > 正文

javascript用户选择突出显示

如何解决《javascript用户选择突出显示》经验,为你挑选了4个好方法。

我正在尝试使用javascript来突出显示用户在单击某个奇数突出显示按钮时选择的文本(如突出显示的文本).它只需要与WebKit或Firefox一起使用,但它似乎几乎不可能,因为它必须在以下情况下工作:

this is text

I eat food

当用户在浏览器中选择"is text"到"I eat"时(不能只是在那里放一个跨度).

这种情况:

this is textmiddle textthis is text

当用户在浏览器中选择"is text"到"this is"时(即使你可以在选择中的每个元素周围包含你的高亮显示,我希望你看到你试图让中间文本突出显示).

这个问题似乎没有在任何地方得到解决,坦率地说我怀疑这是可能的.

如果你可以从选择中得到的Range作为一个完整的html字符串,可以解析然后替换,这是可能的,但据我所知,你不能得到一个范围的原始html ..可怜.



1> underemploye..:

这个答案对你来说可能要晚了几年,但是我遇到了类似的问题,想在这里记录下来,因为这是谷歌的第一次打击.

重申一下,问题是你想从用户选择中捕获Range对象并用样式化的div包围它,如下所示:

function highlightSelection() {
    var userSelection = window.getSelection().getRangeAt(0);
    highlightRange(userSelection);

}

function highlightRange(range) {
    var newNode = document.createElement("div");
    newNode.setAttribute(
       "style",
       "background-color: yellow; display: inline;"
    );
    range.surroundContents(newNode);
}

但正如原始父母所说,这是不安全的.如果选择不跨越元素边界,它将起作用,但如果用户选择创建的范围是跨越HTML标记边界的不安全范围,则它将抛出DOM错误.


解决方案是生成一个较小的Range对象数组,这些对象都不是单独穿过元素屏障,而是共同覆盖用户选择的范围.这些安全范围中的每一个都可以如上突出显示.

function getSafeRanges(dangerous) {
    var a = dangerous.commonAncestorContainer;
    // Starts -- Work inward from the start, selecting the largest safe range
    var s = new Array(0), rs = new Array(0);
    if (dangerous.startContainer != a)
        for(var i = dangerous.startContainer; i != a; i = i.parentNode)
            s.push(i)
    ;
    if (0 < s.length) for(var i = 0; i < s.length; i++) {
        var xs = document.createRange();
        if (i) {
            xs.setStartAfter(s[i-1]);
            xs.setEndAfter(s[i].lastChild);
        }
        else {
            xs.setStart(s[i], dangerous.startOffset);
            xs.setEndAfter(
                (s[i].nodeType == Node.TEXT_NODE)
                ? s[i] : s[i].lastChild
            );
        }
        rs.push(xs);
    }

    // Ends -- basically the same code reversed
    var e = new Array(0), re = new Array(0);
    if (dangerous.endContainer != a)
        for(var i = dangerous.endContainer; i != a; i = i.parentNode)
            e.push(i)
    ;
    if (0 < e.length) for(var i = 0; i < e.length; i++) {
        var xe = document.createRange();
        if (i) {
            xe.setStartBefore(e[i].firstChild);
            xe.setEndBefore(e[i-1]);
        }
        else {
            xe.setStartBefore(
                (e[i].nodeType == Node.TEXT_NODE)
                ? e[i] : e[i].firstChild
            );
            xe.setEnd(e[i], dangerous.endOffset);
        }
        re.unshift(xe);
    }

    // Middle -- the uncaptured middle
    if ((0 < s.length) && (0 < e.length)) {
        var xm = document.createRange();
        xm.setStartAfter(s[s.length - 1]);
        xm.setEndBefore(e[e.length - 1]);
    }
    else {
        return [dangerous];
    }

    // Concat
    rs.push(xm);
    response = rs.concat(re);    

    // Send to Console
    return response;
}

然后可以(似乎)突出显示用户选择,使用此修改后的代码:

function highlightSelection() {
    var userSelection = window.getSelection().getRangeAt(0);
    var safeRanges = getSafeRanges(userSelection);
    for (var i = 0; i < safeRanges.length; i++) {
        highlightRange(safeRanges[i]);
    }
}

请注意,您可能需要一些更高级的CSS来使用户可以看起来很好的许多不同的元素.我希望最终这有助于互联网上的其他一些疲惫的灵魂!



2> 小智..:

好吧,你可以使用DOM操作来完成它.这适用于Firefox:

var selection = window.getSelection();
var range = selection.getRangeAt(0);
var newNode = document.createElement("span");
newNode.setAttribute("style", "background-color: pink;");
range.surroundContents(newNode); 

似乎也适用于当前版本的Safari.请参阅https://developer.mozilla.org/en/DOM/range.surroundContents和http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/ranges.html


如果选择跨越元素边界(例如,如果它跨越多个段落),则这不起作用.

3> Muhammad Bil..:

这是一个完整的代码,用于突出显示和取消高亮显示文本


    
        
            
        

        
            

Hello How are you

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.


https://jsfiddle.net/Bilalchk123/1o4j0w2v/



4> 小智..:

这是我第一次在这里发帖,但看看你的答案,不会有这样的工作吗?我在这里有一个示例:http: //henriquedonati.com/projects/Extension/extension.html

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

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有