2010-01-09 76 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