3

I highlighted selected text using JavaScript with the following code:

var sel = window.getSelection();
if(!sel.isCollapsed) {
    var range = sel.getRangeAt(0);
    sel.removeAllRanges();
    document.designMode = "on";
    sel.addRange(range);
    document.execCommand("HiliteColor", false, "#ffffcc");
    sel.removeAllRanges();
    document.designMode = "off";
}

How do I then remove the highlighted color and restore the text?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
PhoenixJon
  • 43
  • 1
  • 2
  • 8
  • There are a *lot* of cross-browser hassles with this stuff. You might want to look at a library called [Rangy](http://code.google.com/p/rangy/) that helps smooth them over, and offers highlighting features as in [this demo](http://rangy.googlecode.com/svn/trunk/demos/highlighter.html). (I have no affiliation with Rangy.) – T.J. Crowder Nov 10 '11 at 10:13
  • Tricky. I've seen this asked before and there's no easy way. – Tim Down Nov 10 '11 at 10:24
  • Re Rangy, I'm the author, and it won't really help you with this (yet: I'm working on it), unless you used a CSS class to do the highlighting instead, in which case you could use the CSS class applier module: http://code.google.com/p/rangy/wiki/CSSClassApplierModule – Tim Down Nov 10 '11 at 10:26
  • @T.J.Crowder Can I use Rangy library with UIWebView on ios4.2 or later platform? – PhoenixJon Nov 12 '11 at 13:33
  • Yes, Rangy works in Mobile Safari and in `UIWebView`. – Tim Down Nov 12 '11 at 16:41
  • @TimDown Thanks. You know how to save highlight and notes with Rangy? I think I have to use sqlite like database. – PhoenixJon Nov 12 '11 at 16:54
  • I'm still working on that module and it hasn't made it into a full release yet, so I'd hold off from using it in production for a little while. – Tim Down Nov 12 '11 at 23:54
  • @TimDown I hope it will release soon. – PhoenixJon Nov 13 '11 at 15:39
  • I just had this problem and was able to solve it by setting the backColor to transparent when I want to undo a highlight. May not be the perfect solution, but it works with dynamic background colors which was a main requirement for me. – Lizza Feb 14 '14 at 19:33

3 Answers3

8

Here's some code to add and remove highlights. It's too long to post here practically, so I've made a demo and posted a snippet below. It's not quite ideal because the unhighlight() function doesn't remove <span> elements inserted by the highlight command, but with a little care this would be a possible addition.

Live demo: http://jsfiddle.net/timdown/Bvd9d/

Code snippet:

function unhighlight(node, colour) {
    if (!(colour instanceof Colour)) {
        colour = new Colour(colour);
    }

    if (node.nodeType == 1) {
        var bg = node.style.backgroundColor;
        if (bg && colour.equals(new Colour(bg))) {
            node.style.backgroundColor = "";
        }
    }
    var child = node.firstChild;
    while (child) {
        unhighlight(child, colour);
        child = child.nextSibling;
    }
}
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • 1
    Tim, this is amazing. For some reason the unhighlight fn was giving me an error when it tries to create a new Colour object (in the wild). No worries though, I'm not particular that the unhighlight color matches the highlight color; I'd rather just get rid of all highlights. So, to get around it, I just removed the condition "if(bg && colour.equals(new Colour(bg)))". Thanks. – amp343 Feb 08 '12 at 23:21
  • @Tim Down Could you please check this.. In demo the button is not highlighting. Please check. It would be great help. – Exception Feb 25 '12 at 20:25
  • @SoI: I think I missed you comment. Which browser is showing the problem? – Tim Down Nov 28 '12 at 09:18
  • 1
    @Tim Down: rather than just get rid of all highlights can we unhighlight any specific selected highlighted text area ? – prime Sep 13 '13 at 03:23
  • Yes we can. Use the solution posted in http://stackoverflow.com/questions/1335252/how-can-i-get-the-dom-element-which-contains-the-current-selection – ABCD Oct 31 '14 at 06:01
4

You could use CSS instead:

<style>
    ::selection {background-color: #ffffcc;}
</style>

EDIT: Update in response to comment and clarification

<script type="text/javascript">
    var spans = document.getElementsByTagName('span'), i;
    for( i=0; i<spans.length; i++) {
       if( spans[i].style.backgroundColor == "#ffffcc") {
           // Two alternatives. This:
           spans[i].style.backgroundColor = "transparent";
           // OR this, if spans contain only text:
           spans[i].parentNode.replaceChild(spans[i].firstChild,spans[i]);
           i--;
           // End alternatives - only include i-- in the second one
       }
    }
</script>

Although, this fails in some browsers (I think it's Firefox) where the element style is changed to the computed style.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • 1
    I think you misunderstand my question. I want to do it dynamically using javascript. – PhoenixJon Nov 10 '11 at 07:54
  • 1
    @PhoenixJon this *will* be dynamic. It'll change the background color of only the text that is selected. Not using JavaScript, but it'll work like you want it to. – Some Guy Nov 10 '11 at 07:55
  • @Amaan Thanks for your comment. Er.. What i want is when i select the text and press "highlight" button, then the selected text remains highlighted. And again when i pressed "remove" button, highlighted text becomes normal text. Something like this.. – PhoenixJon Nov 10 '11 at 07:59
  • Thanks. I want to know when execCommand is executed, the span tag is added? If so, tag name or id exists in that tag? or only set background color? – PhoenixJon Nov 10 '11 at 11:53
  • The last time I checked, the command wraps a `` tag around the range with the appropriate style applied. – Niet the Dark Absol Nov 10 '11 at 12:08
-1

Use

sel.removeAllRanges()
Nightfirecat
  • 11,432
  • 6
  • 35
  • 51
satin
  • 697
  • 2
  • 7
  • 19
  • and i dont think u'll need to do anything else . all the background color will be restored automatically . – satin Nov 10 '11 at 08:15
  • 1
    He's *already* using `removeAllRanges`. The issue is that he's executed the `hilitecolor` command on a range, and so it now has that, and he wants to remove it later. – T.J. Crowder Nov 10 '11 at 08:47