4/04/2007

IE's TextRange.compareEndPoints()

0 comments

TextRange object

The other day I was coding a web page that needs to make use of some javascript functions of textarea element. I did a little dig-out and ran into this compareEndPoints function. It is a function attached to a TextRange object. The IE-specific TextRange object serves as a mediator for the text input element (<input> with type="text", <textarea>...) to manupilate text-related operations (search, replace, copy, paste, insert ...).

Now assuming we have a <textarea> element object called oTextArea, a TextRange object can be created in one of the following ways:
  1. var oTR1 = oTextArea.createTextRange()
  2. var oTR2 = document.selection.createRange()
These code should appear inside an eventhandler, for example:

  oTextArea.onselect = function(){
...
var oTR1= this.createTextRange()
var oTR2= document.selection.createRange()
...
}

Both oTR1 and oTR2 are a TextRange object that has the following properties:

PropertiesoTR1oTR2
boundingHeight1616
boundingLeft15141
boundingTop124124
boundingWidth25256
offsetLeft15141
offsetTop124124
textThis is the test
<textarea> element
textarea
htmlTextThis is the test
&lt;textarea&gt; element.
textarea

Note that:
  1. What createTextRange returns (=oTR1) covers the entire value range of <textarea> while createRange covers only the range of text that is selected;
  2. All the numerical property values in TextRange object are in pixel. No information of index (the start and end point for the selected text range) is available;

compareEndPoints (type, textRange)

I won't go through all the methods of the TextRange object but this one compareEndPoints(type, textRange). This function checks the relationship between two TextRange objects by comparing the starting and ending indices of textRange.text :

  textRange1.compareEndPoints("StartToStart", textRange2)

The argument type can be one of the fillowing 4 : "StartToStart", "StartToEnd", "EndToStart" and "EndToEnd". When it is "StartToStart", it compares the starting index of textRange1.text with the that of textRange2.text. The return is either -1, 0 or 1.

Now, the reason that I talk about this compareEndPoints specifically. Since it is used upon two TextRange objects, and as we saw earlier that both createRange() and createTextRange() return a TextRange object, instinctly it would work like this:

   var oTR1= oTextArea.createTextRange()
var oTR2= document.selection.createRange()
var x = oTR1.compareEndPoints("StartToStart", oTR2)

However, it won't work. IE rejects this usage by showing "illegal argument" error. It took me a while of searching and code digging to figure out a way to do this:

   var oTR1 = document.body.createTextRange(); // Create TextRange on entire body 
oTR1.moveToElementText(oTextArea) // Use moreToElementText to move
// the TextRange to the textarea

var oTR2= document.selection.createRange();
var x = oTR1.compareEndPoints("StartToStart", oTR2)

Only when the createTextRange( ) is used in this way can the resulting TextRange object be used together in compareEndPoints( ) with that generated by createRange( ).