2014-01-29 122 views
0

我使用a script from Tim Down創建高光。現在,我希望用戶再次點擊瀏覽器操作以將其刪除。從DOM刪除添加的高亮

我以爲我可以添加其他if聲明,這個片段:

function makeEditableAndHighlight(colour) { 
    var range, sel = window.getSelection(); 
    if (sel.rangeCount && sel.getRangeAt) { 
     range = sel.getRangeAt(0); 
    } 
    document.designMode = "on"; 
    if (range) { 
     sel.removeAllRanges(); 
     sel.addRange(range); 
    } 
    // Use HiliteColor since some browsers apply BackColor to the whole block 
    if (!document.execCommand("HiliteColor", false, '#FFFF00')) { 
     document.execCommand("BackColor", false, '#FFFF00'); 
    } 
    if (!document.execCommand("HiliteColor", true, '#FFFF00')) { // Added this logic 
     document.execCommand("removeFormat", false, null); 
    } 
    document.designMode = "off"; 
} 

我的想法是,如果"HiliteColor"返回true,它會刪除格式,但它不工作。有什麼想法嗎?

編輯 做更多的閱讀後,我瞭解到,在execCommand布爾沒有任何與返回的值。我怎樣才能改善我的邏輯以扭轉背景顏色?它是否可行?

回答

2

您需要一種「序列化」選定範圍以供以後訪問的方法。
This answer解釋瞭如何實現序列化/反序列化。

您的代碼看起來是這樣的:

var serializedRange; 

/* Serializes and returns the specified range 
* (ignoring it if its length is zero) */ 
function serializeRange(range) { 
    return (!range || ((range.startContainer === range.endContainer) 
         && (range.startOffset === range.endOffset))) 
      ? null : { 
       startContainer: range.startContainer, 
       startOffset: range.startOffset, 
       endContainer: range.endContainer, 
       endOffset:  range.endOffset 
      }; 
} 

/* Restores the specified serialized version 
* (removing any ranges currently seleted) */ 
function restoreRange(serialized) { 
    var range = document.createRange(); 
    range.setStart(serialized.startContainer, serialized.startOffset); 
    range.setEnd(serialized.endContainer, serialized.endOffset); 

    var sel = window.getSelection(); 
    sel.removeAllRanges(); 
    sel.addRange(range); 
} 

/* Hilites the currently selected range or removes the hilite 
* (if there is a previously serialized range) */ 
function toggleHilite() { 
    document.designMode = 'on'; 

    var sel = window.getSelection(); 
    if (serializedRange) { 
     /* There is a hilited range, let's remove the hilite */ 
     restoreRange(serializedRange); 
     serializedRange = null; 
     document.execCommand('removeFormat', false, null); 
     sel.removeAllRanges(); 
    } else { 
     /* There is no hilited range, so hilite 
     * the currently selected range (if any) */ 
     if (sel.rangeCount && sel.getRangeAt) { 
      document.execCommand('hiliteColor', false, '#FFFF00'); 
      serializedRange = serializeRange(sel.getRangeAt(0)); 
      // it is important to serialize the range *after* hiliting, 
      // because `execCommand` will change the DOM affecting the 
      // range's start-/endContainer and offsets. 
     } 
    } 

    document.designMode = 'off'; 
} 
+0

這真是太棒了!非常感謝您的幫助。 – Brian

+0

總是樂於幫忙! (只是單挑:我在'serializeRange()'做了一個小改進。) – gkalpak

+0

好吧,因爲我還在學習,我只是爲了確保我理解這個改變:你添加的'==='確保選擇的開始/結束點不會被DOM重構搞亂,對吧?換句話說,如果這些值不相同,它會測試假廣告,然後**添加**突出顯示而不是刪除? – Brian