2010-01-09 77 views
3

如何在Firefox中使用PURE JavaScript替换选定的文本与另一个文本?替换Firefox中的选定文本

这是我用得到的选择:

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> 

用户选择下面的文本(通过一个选择):

他是一个考验还在测试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> 

回答

6

Wooove,这是一个贝蒂!

的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第一公共父元素搜索,但我不知道该怎么做......

编辑

我裹了进去if(range.collapsed == false)的到-X功能并使用range.commonAncestorContainer.childNodes[0]为了开始迭代通过选择的开始和结束位置的共同父母的第一个孩子的元素

+0

这太棒了!对于父元素,我认为我们可以使用range.commonAncestorContainer,并检查边界range.compareBoundaryPoints。 请看看它是否可以用于你的代码(我认为它可以),无论如何,即使它是mot我会接受你的答案后,您的意见:)谢谢 – kenny 2010-01-09 15:46:19

+0

我认为这是range.comparePoint而不是range.compareBoundaryPoints – kenny 2010-01-09 16:22:42

+0

请注意,如果选定的文本位于文本框内,这不起作用。如果你想看到什么:http://stackoverflow.com/questions/4714192/insert-text-before-and-after-selection-in-textarea-with-javascript/4714850#4714850 – 2011-01-28 13:02:53