javascript - 在 Firefox 中替换选定的文本

标签 javascript

如何在 Firefox 中使用 PURE javascript 将所选文本替换为另一个文本?

我用它来获取选择:

var sel = this.getSelection();
var range = sel.getRangeAt(0);

还有这个重要的问题:
我想保留原来的字符格式(当然新字符串会有正确的格式)
选择可以“跨元素”完成(我的意思是选择可以包含来自一个元素(如 div 或表格)的一些文本和来自另一个元素的一些文本)。

例如,文档:

<div>
 this is a test
</div>
<div>
<b>still a test</b>
</div>
 <table style="width:100%;">
        <tr>
            <td>
                another word</td>
            <td>
                stackoverflow</td>
        </tr>
        <tr>
            <td>
                bump</td>
            <td>
               </td>
        </tr>
    </table>

用户选择以下文本(通过一次选择):

his is a test still a test anot

所以现在我想替换保持格式的文本,例如用新字符串替换所有内容 =

XXX XX X XXXX XXXXX X XXXX XXXX

最终文档(替换后)将是:

<div>
 tXXX XX X XXXX
</div>
<div>
<b>XXXXX X XXXX</b>
</div>
 <table style="width:100%;">
        <tr>
            <td>
                XXXXher word</td>
            <td>
                stackoverflow</td>
        </tr>
        <tr>
            <td>
                bump</td>
            <td>
               </td>
        </tr>
    </table>

最佳答案

呜呜呜,太可惜了!

Javascript

var sel, range, nodevalue, startFound, stop;

function goThroughElements(el){
    // If el is the start node, set startFound to true
    if(el.isSameNode(range.startContainer)) startFound = true;
    
    if(startFound){
        // If this is the start node, replace the text like this: abcd[ef gh] --> abcdxx xx
        if(el.isSameNode(range.startContainer)){
            // \w stands for a word character
            nodevalue = el.nodeValue.substring(range.startOffset).replace(/\w/g, 'x');
            el.nodeValue = el.nodeValue.substring(0, range.startOffset) + nodevalue;
            
        }

        // If this is the end node, replace the value like this: [abc def]gh ij -> xxx xxxgh ij
        else if(el.isSameNode(range.endContainer)){
            nodevalue = el.nodeValue.substring(0,range.endOffset).replace(/\w/g, 'x');
            el.nodeValue = nodevalue + el.nodeValue.substring(range.endOffset);
            
            // Now we can stop
            stop = true;
        }
        
        // If this is just a text node, replace the value by xxxx
        else if(el.nodeType == 3){
            el.nodeValue = el.nodeValue.replace(/\w/g, 'x')
        }
    }
    
    // Loop trough el's brothers
    while(el){
        // Stop if we need to
        if(stop) return;
        
        // If this element has child nodes, call this function again with the first child node
        if(el.hasChildNodes()){
            goThroughElements(el.childNodes[0]);
        }
        
        // Jump to el's brother, or quit the loop
        if(el.nextSibling)
            el = el.nextSibling;
        else
            break;
    }
    
}
    
$(document).ready(function() {
    $(this).mouseup(function(){
        // Get the selection
        sel = window.getSelection();
        range = sel.getRangeAt(0);
        
        // Stop must be false if the last selected text node isn't found, startFound must be false when the start isn't found
        stop = false; startFound = false;
        
        if(range.collapsed == false){
            // Check if the selection takes place inside one text node element
            if(range.startContainer.isSameNode(range.endContainer)){
                // ab[cdefg]h  -> aaxxxxxh
                nodevalue = range.startContainer.nodeValue;
                range.startContainer.nodeValue = nodevalue.substring(0, range.startOffset) + nodevalue.substring(range.startOffset, range.endOffset).replace(/\w/g, 'x') + nodevalue.substring(range.endOffset);
            } else {    
                // If the start node of the selection isn't the same as the end node, loop through all elements
                goThroughElements(range.commonAncestorContainer.childNodes[0]);
            }
            // Collapse selection.
            range.collapse(true);
        }            
    });
});

示例

您可以 try the code当然

也许这不是最佳解决方案,因为它从根开始搜索起始节点。从 range.startContainerrange.endContainer 的第一个公共(public)父元素开始搜索会更快,但我不知道该怎么做...

编辑

我将 to-X 函数包装在 if(range.collapsed == false) 中并使用 range.commonAncestorContainer.childNodes[0] 以开始迭代选择的开始和结束位置的公共(public)父元素的第一个子元素

关于javascript - 在 Firefox 中替换选定的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2033244/

相关文章:

javascript - 在 MochaJS 测试套件中使用 --globals 变量

javascript - 具有无服务器框架(BlitzJs)的 Websocket api?

javascript - Angular 2简单动画

javascript - 使用submit()函数时不触发不引人注目的验证

javascript - 将 helper 应用于所有集合 mongodb/meteor

javascript - .val() 替代方法,获取匹配元素集中所有元素的当前值

javascript - 使用 Node.js 生成 .lnk Windows 快捷方式会出现 "UNKNOWN"错误

javascript - 从网页启动 Windows 文件资源管理器窗口

php - 如何通过强制另存为选项来保存网页的内容/文本

javascript - 有两个圆圈和一个点。如何沿着它绕圈