5

I am using contenteditable and highlighting some text. I want to then backup that text range, and at a later time give that range(text) a different color. If I check in my zss_editor.restorerange method I do get back a valid selection object, so it must be something incorrect in how I am previously saving that range.

var zss_editor = {};

// The current selection
zss_editor.currentSelection;

zss_editor.backuprange = function(){
    var selection = window.getSelection();
    zss_editor.currentSelection = selection.getRangeAt(0);
    zss_editor.currentSelection.setEnd(zss_editor.currentSelection.startContainer, zss_editor.currentSelection.startOffset);
}

zss_editor.restorerange = function(){
    var selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(zss_editor.currentSelection);
    console.log(zss_editor.currentSelection);
}

zss_editor.setTextColor = function(color) {
    zss_editor.restorerange();
    document.execCommand("styleWithCSS", null, true);
    document.execCommand('foreColor', false, color);
    document.execCommand("styleWithCSS", null, false);
}

zss_editor.setBackgroundColor = function(color) {
    zss_editor.restorerange();
    document.execCommand("styleWithCSS", null, true);
    document.execCommand('hiliteColor', false, color);
    document.execCommand("styleWithCSS", null, false);
}

Working example on JS Fiddle: http://jsfiddle.net/zedsaid/gC3jq/11/

Why, when I backup the range and want to restore it at a latter time, does it not work? Do I need to backup the range in a different way?

j08691
  • 204,283
  • 31
  • 260
  • 272
Nic Hubbard
  • 41,587
  • 63
  • 251
  • 412
  • Your'e not creating a "back-up" of the range, you'd need [`cloneRange()`](https://developer.mozilla.org/en-US/docs/Web/API/Range.cloneRange) to copy a range. – Teemu Jan 07 '14 at 18:01
  • @Teemu Can you post an example? – Nic Hubbard Jan 07 '14 at 19:21
  • 1
    [Here](http://jsfiddle.net/d7UMt/)... Though there's something odd when changing the background, it changes after blurring and refocusing the window. – Teemu Jan 07 '14 at 19:23

1 Answers1

10

You can backup the range by storing the startContainer & startOffset as well as the endContainer & endOffset. To restore, you just create a new range object and set the start and end of that range object then add it to the selection

var zss_editor = {};

// The current selection
zss_editor.currentSelection;

zss_editor.backuprange = function(){
    var selection = window.getSelection();
    var range = selection.getRangeAt(0);
    zss_editor.currentSelection = {"startContainer": range.startContainer, "startOffset":range.startOffset,"endContainer":range.endContainer, "endOffset":range.endOffset};

}

zss_editor.restorerange = function(){
    var selection = window.getSelection();
    selection.removeAllRanges();
    var range = document.createRange();
    range.setStart(zss_editor.currentSelection.startContainer, zss_editor.currentSelection.startOffset);
    range.setEnd(zss_editor.currentSelection.endContainer, zss_editor.currentSelection.endOffset);
    selection.addRange(range);
    console.log(range);
}

zss_editor.setTextColor = function(color) {
    zss_editor.restorerange();
    document.execCommand("styleWithCSS", null, true);
    document.execCommand('foreColor', false, color);
    document.execCommand("styleWithCSS", null, false);
}

zss_editor.setBackgroundColor = function(color) {
    zss_editor.restorerange();
    document.execCommand("styleWithCSS", null, true);
    document.execCommand('hiliteColor', false, color);
    document.execCommand("styleWithCSS", null, false);
}

$('#backup').click(function() {
    zss_editor.backuprange();
});

$('#color1').click(function() {
    zss_editor.setTextColor('#007AFF');
});

$('#color2').click(function() {
    zss_editor.setBackgroundColor('#007AFF');
});
T.V.
  • 505
  • 3
  • 10
  • That gives me the error: `TypeError: '[object RangeConstructor]' is not a constructor (evaluating 'new Range()')` – Nic Hubbard Jan 07 '14 at 19:20
  • What browser are you using? I didn't receive an error when testing it in JSFiddle – T.V. Jan 07 '14 at 19:28
  • Using Safari for testing. – Nic Hubbard Jan 07 '14 at 19:30
  • I've made a change to the code to use document.createRange() instead of using new Range(). That should hopefully resolve the issue. – T.V. Jan 07 '14 at 19:35
  • Would it be easy to bring focus back to that range? E.g. highlight it again? – Nic Hubbard Jan 07 '14 at 19:51
  • the selection.addRange() call should have re-highlighted the range for you. As I don't have access to a safari browser I'm not sure if the calls to the execCommand() may have cause the range to not be highlighted. what you can do is call restorerange() again after executing all your execCommand() calls and see if that does the trick – T.V. Jan 07 '14 at 20:50
  • 1
    No, it doesn't work in Firefox or Safari. It gives it color like I want, but I would love to give that range focus again and have it selected. – Nic Hubbard Jan 07 '14 at 23:29
  • Hi T.V. Storing JSON.stringify(zss_editor.currentSelection.startContainer) in the chrome storage gives "{ }" empty string object. Same is with endContainer. How can we store the object? Could you please help me out? – Shailaja shah Jan 21 '18 at 20:23