0

I have a bit of code that returns the text of a selection and I can assign that string to a variable, but now all I need are two variables, one for the text before the selection and one for the text after the selection. Here is the code for getting the selection:

function findSelection(){ //returns the selection object.
    var userSelection;
    if (window.getSelection) {userSelection = window.getSelection();} // Mozilla Selection object.
        else if (document.selection){userSelection = document.selection.createRange();} //gets Microsoft Text Range, should be second b/c Opera has poor support for it.
    if (userSelection.text){return userSelection.text} //for Microsoft Objects.
        else {return userSelection} //For Mozilla Objects.
    }

Then I find the anchorOffset and focusOffset to find the caret positions. I tried using these to modify a range object, like this:

var range = document.createRange();
range.setStart(textdiv,0);
range.setEnd(textdiv,5);

Where textdiv is a variable holding the last div the user clicked on. The problem is firefox just gives me a "Security error" code: "1000" at the line range.setStart(textdiv,0);.

Is there an easier way to go about doing this? I really just need the text and nothing more.

DavidR
  • 5,350
  • 6
  • 30
  • 36
  • This `findSelection` function is flawed, as I explained in my (apparently ignored) answer to your question about this piece of code: http://stackoverflow.com/questions/2820650/javascript-functions-return-lines-of-function-code-or-native-code-what-am/2825473#2825473 – Tim Down May 14 '10 at 10:04

3 Answers3

0
//returns the selection object.
function findSelection(){ 
  var userSelection;
  if (window.getSelection) {
    userSelection = window.getSelection();
  } // Mozilla Selection object.
  else if (document.selection){
    userSelection = document.selection.createRange();
  } //gets Microsoft Text Range, should be second b/c Opera has poor support for it.
  if (userSelection.text){
    return userSelection.text
  } //for Microsoft Objects.
  else {
    return userSelection
  } //For Mozilla Objects.
}

//get strings before and after selection
function getOuterRange(selection) {
  var rangeBefore = document.createRange();
  var rangeAfter = document.createRange();
  var r = selection.getRangeAt(0);

  rangeBefore.setStart(r.startContainer,0);
  rangeBefore.setEnd(r.startContainer,r.startOffset);

  rangeAfter.setStart(r.endContainer,r.endOffset);
  rangeAfter.setEnd(r.endContainer,r.endContainer.length);

  return {
    before: rangeBefore.toString(),
    after: rangeAfter.toString()
  }
}

console.log(getOuterRange(findSelection()));
Andrew K
  • 646
  • 5
  • 6
-1

Here's an expression for the first value (non-Evil-Empire version only):

window.getSelection().anchorNode.textContent.substring(0,
                window.getSelection().anchorOffset)
Michael Lorton
  • 43,060
  • 26
  • 103
  • 144
  • This is OK if the `anchorNode` is a text node, but if the `anchorNode` is an element (which it may well be) `anchorOffset` will be a node offset rather than a character offset, so this will either give an error or an incorrect value. – Tim Down May 14 '10 at 14:20
-1

The answers can be found in the documentation for DOM Range. There's the official spec, or if you prefer, there's an MDN article.

The problem is that your code attempts to set the start and end boundaries of the range to the 0th and 5th child node of the div respectively. If you need to work on character offsets within text, you need to work with text nodes. Assuming your textdiv contains a single text node, you can do something like the following for non-IE browsers:

var textNode = textdiv.firstChild;
range.setStart(textNode, 0);
range.setEnd(textNode, 0);

In older versions of IE (<= 8), there is no DOM Range and you'll have to use IE's proprietary TextRange instead. Only for the specific case of an element containing a single text node, the following will work:

var range = document.body.createTextRange();
range.moveToElementText(textdiv);
range.collapse();
range.moveStart("character", 0);
range.moveEnd("character", 5);
Tim Down
  • 318,141
  • 75
  • 454
  • 536