2014-01-29 66 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