A Range identifies a range of content in a Document, DocumentFragment or Attr. It is contiguous in the sense that it can be characterized as selecting all of the content between a pair of boundary-points.
In a text editor or a word processor, a user can make a selection by pressing down the mouse at one point in a document, moving the mouse to another point, and releasing the mouse. The resulting selection is contiguous and consists of the content between the two points.
The term 'selecting' does not mean that every Range corresponds to a selection made by a GUI user; however, such a selection can be returned to a DOM user as a Range.
In bidirectional writing (Arabic, Hebrew), a range may correspond to a logical selection that is not necessarily contiguous when displayed. A visually contiguous selection, also used in some cases, may not correspond to a single logical selection, and may therefore have to be represented by more than one range.
The Range interface provides methods for accessing and manipulating the document tree at a higher level than similar methods in the Node interface. The expectation is that each of the methods provided by the Range interface for the insertion, deletion and copying of content can be directly mapped to a series of Node editing operations enabled by DOM Core. In this sense, the Range operations can be viewed as convenience methods that also enable the implementation to optimize common editing patterns.
This chapter describes the Range interface, including methods for creating and moving a Range and methods for manipulating content with Ranges.
The interfaces found within this section are not mandatory. A DOM
application may use the hasFeature(feature, version) method
of the DOMImplementation interface with parameter values
"Range" and "2.0" (respectively) to determine whether or not this module
is supported by the implementation. In order to fully support this
module, an implementation must also support the "Core" feature defined
defined in the DOM Level 2 Core specification
This chapter refers to two different representations of a document:
the text or source form that includes the document markup and the tree
representation similar to the one described in the
introduction section of the DOM Level 2 Core
A Range consists of two
The
The
In terms of the text representation of a document, the
The relationship between locations in a text representation of the document and in the Node tree interface of the DOM is illustrated in the following diagram:
In this diagram, four different Ranges are illustrated. The
Notice that the
The
Many of the examples in this chapter are illustrated using a text
representation of a document. The
When both
A Range is created by calling the createRange() method on
the DocumentRange interface. This interface can be obtained from
the object implementing the Document interface using
binding-specific casting methods.
The initial state of the Range returned from this method is such that both
of its
Like some objects created using methods in the Document interface (such as
Nodes and DocumentFragments), Ranges created via a particular document instance
can select only content associated with that Document, or with
DocumentFragments and Attrs for which that Document is
the ownerDocument. Such Ranges, then, can not be used with other
Document instances.
A Range's position can be specified by setting the setStart and setEnd methods.
If one boundary-point of a Range is set to have a
The start position of a Range is guaranteed to never be after the end
position. To enforce this restriction, if the start is set to be at a position
after the end, the Range is
It is also possible to set a Range's position relative to nodes in the tree:
The setStart()and setEnd().
A Range can be
Passing TRUE as the parameter toStart will FALSE
to its end.
Testing whether a Range is collapsed attribute:
The following methods can be used to make a Range select the contents of a
node or the node itself.
The following examples demonstrate the operation of the
methods selectNode and selectNodeContents:
It is possible to compare two Ranges by comparing their boundary-points:
where CompareHow is one of four
values: START_TO_START, START_TO_END,
END_TO_END and END_TO_START. The return value is -1, 0 or 1
depending on whether the corresponding boundary-point of the Range is before,
equal to, or after the corresponding boundary-point of
sourceRange. An exception is thrown if the two Ranges have
different
The result of comparing two boundary-points (or positions) is specified below. An informal but not always correct specification is that an boundary-point is before, equal to, or after another if it corresponds to a location in a text representation before, equal to, or after the other's corresponding location.
In the first case the boundary-points have the same
In the second case a child node C of the
In the third case a child node C of the
In the fourth case, none of three other cases hold: the containers of A and
B are
Note that because the same location in a text representation of the document can correspond to two different positions in the DOM tree, it is possible for two boundary-points to not compare equal even though they would be equal in the text representation. For this reason, the informal definition above can sometimes be incorrect.
One can delete the contents selected by a Range with:
deleteContents() deletes all nodes and characters selected by
the Range. All other nodes and characters remain in the
After deleteContents() is invoked on a Range, the Range
is
Note that if deletion of a Range leaves adjacent Text nodes, they are not
automatically merged, and empty Text nodes are not automatically removed. Two
Text nodes should be joined only if each is the container of one of the
boundary-points of a Range whose contents are deleted. To merge adjacent Text
nodes, or remove empty text nodes, the normalize() method on
the Node interface should be used.
If the contents of a Range need to be extracted rather than deleted, the
following method may be used:
The extractContents() method removes nodes from the
Range's deleteContents() method. In addition, it places the deleted
contents in a new DocumentFragment. The following examples
illustrate the contents of the returned DocumentFragment:
It is important to note that nodes that are
The contents of a Range may be duplicated using the following method:
This method returns a DocumentFragment that is similar to the
one returned by the method extractContents(). However, in this
case, the original nodes and character data in the Range are not removed from
the Range's DocumentFragment are cloned.
A node may be inserted into a Range using the following method:
The insertNode() method inserts the specified node into the
Range's
If the start boundary point of the Range is in a Text node, the
insertNode operation splits the Text node at the
boundary point. If the node to be inserted is also a Text node,
the resulting adjacent Text nodes are not normalized automatically;
this operation is left to the application.
The Node passed into this method can be a DocumentFragment. In
that case, the contents of the DocumentFragment are inserted at
the start DocumentFragment itself is not. Note that if the
Node represents the root of a sub-tree, the entire sub-tree is inserted.
The same rules that apply to the insertBefore() method on the
Node interface apply here. Specifically, the Node passed in, if it already has
a parent, will be removed from its existing position.
The insertion of a single node to subsume the content selected by a Range
can be performed with:
The surroundContents() method causes all of the content
selected by the Range to be rooted by the specified node. The nodes may not be
Attr, Entity, DocumentType, Notation, Document, or DocumentFragment nodes.
Calling surroundContents() with the Element node FOO in the following
examples yields:
Another way of describing the effect of this method on the Range's
Remove the contents selected by the Range with a call
to extractContents().
Insert the node newParent where the Range is collapsed (after the
extraction) with insertNode().
Insert the entire contents of the extracted DocumentFragment
into newParent. Specifically, invoke the appendChild()
on newParent passing in the DocumentFragment returned as a result of the
call to extractContents()
Select newParent and all of its contents with
selectNode().
The surroundContents() method raises an exception if the
Range surroundContents()raises an exception is:
If the node newParent has any children, those children are removed before its
insertion. Also, if the node newParent already has a parent, it is removed from
the original parent's childNodes list.
One can clone a Range:
This creates a new Range which selects exactly the same content as that
selected by the Range on which the method cloneRange was invoked.
No content is affected by this operation.
Because the boundary-points of a Range do not necessarily have the
same
to get the
One can get a copy of all the character data selected or partially selected
by a Range with:
This does nothing more than simply concatenate all the character data
selected by the Range. This includes character data in both
Text and CDATASection nodes.
As a document is modified, the Ranges within the document need to be updated. For example, if one boundary-point of a Range is within a node and that node is removed from the document, then the Range would be invalid unless it is fixed up in some way. This section describes how Ranges are modified under document mutations so that they remain valid.
There are two general principles which apply to Ranges under document mutation: The first is that all Ranges in a document will remain valid after any mutation operation and the second is that, as much as possible, all Ranges will select the same portion of the document after any mutation operation.
Any mutation of the document tree which affect Ranges can be considered to
be a combination of basic deletion and insertion operations. In fact, it can be
convenient to think of those operations as being accomplished using the
deleteContents() and insertNode() Range methods and,
in the case of Text mutations, the splitText() and
normalize() methods.
An insertion occurs at a single point, the insertion point, in the document.
For any Range in the document tree, consider each boundary-point. The only case
in which the boundary-point will be changed after the insertion is when the
boundary-point and the insertion point have the same
Note that when content is inserted at a boundary-point, it is ambiguous as
to where the boundary-point should be repositioned if its relative position is
to be maintained. There are two possibilities: at the start or at the end of
the newly inserted content. We have chosen that in this case neither
the
Suppose the Range selects the following:
Consider the insertion of the text "inserted text" at the following
positions:
Any deletion from the document tree can be considered as a sequence
of deleteContents() operations applied to a minimal set of disjoint
Ranges. To specify how a Range is modified under deletions we need only
consider what happens to a Range under a single
deleteContents()operation of another Range. And, in fact, we need
only consider what happens to a single boundary-point of the Range since both
boundary-points are modified using the same algorithm.
If a boundary-point of the original Range is within the content being
deleted, then after the deletion it will be at the same position as the
resulting boundary-point of the (now
If a boundary-point is after the content being deleted then it is not
affected by the deletion unless its
If a boundary-point is before the content being deleted then it is not affected by the deletion at all.
In these examples, the Range on which deleteContents()is
invoked is indicated by the underline.
Before:
After:
Before:
After:
Before:
After:
In this example, the container of the start boundary-point after the deletion is the Text node holding the string "ange".
Before:
After:
Before:
After:
To summarize, the complete, formal description of the Range
interface is given below:
Node within which the Range begins
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Offset within the starting node of the Range.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Node within which the Range ends
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Offset within the ending node of the Range.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
TRUE if the Range is collapsed
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
The
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Sets the attributes describing the start of the Range.
The refNode value. This parameter must be different from
null.
The startOffset value.
INVALID_NODE_TYPE_ERR: Raised if refNode or an ancestor of
refNode is an Entity, Notation, or DocumentType node.
INDEX_SIZE_ERR: Raised if offset is negative or greater than
the number of child units in refNode. Child units are refNode is a type of CharacterData node (e.g., a Text or Comment node) or a ProcessingInstruction
node. Child units are Nodes in all other cases.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Sets the attributes describing the end of a Range.
The refNode value. This parameter must be different from
null.
The endOffset value.
INVALID_NODE_TYPE_ERR: Raised if refNode or an ancestor of
refNode is an Entity, Notation, or DocumentType node.
INDEX_SIZE_ERR: Raised if offset is negative or greater than
the number of child units in refNode. Child units are refNode is a type of CharacterData node (e.g., a Text or Comment node) or a ProcessingInstruction
node. Child units are Nodes in all other cases.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Sets the start position to be before a node
Range starts before refNode
INVALID_NODE_TYPE_ERR: Raised if the root container of
refNode is not an Attr, Document, or DocumentFragment node or if
refNode is a Document, DocumentFragment, Attr, Entity, or Notation
node.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Sets the start position to be after a node
Range starts after refNode
INVALID_NODE_TYPE_ERR: Raised if the root container of refNode is
not an Attr, Document, or DocumentFragment node or if refNode is a
Document, DocumentFragment, Attr, Entity, or Notation node.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Sets the end position to be before a node.
Range ends before refNode
INVALID_NODE_TYPE_ERR: Raised if the root container of refNode is
not an Attr, Document, or DocumentFragment node or if refNode is a
Document, DocumentFragment, Attr, Entity, or Notation node.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Sets the end of a Range to be after a node
Range ends after refNode.
INVALID_NODE_TYPE_ERR: Raised if the root container of
refNode is not an Attr, Document or DocumentFragment node or if
refNode is a Document, DocumentFragment, Attr, Entity, or Notation
node.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Collapse a Range onto one of its boundary-points
If TRUE, collapses the Range onto its start; if FALSE, collapses it onto its end.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Select a node and its contents
The node to select.
INVALID_NODE_TYPE_ERR: Raised if an ancestor of refNode is an
Entity, Notation or DocumentType node or if refNode is a Document,
DocumentFragment, Attr, Entity, or Notation node.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Select the contents within a node
Node to select from
INVALID_NODE_TYPE_ERR: Raised if refNode or an ancestor of
refNode is an Entity, Notation or DocumentType node.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Passed as a parameter to the compareBoundaryPoints method.
Compare start boundary-point of sourceRange to start
boundary-point of Range on which compareBoundaryPoints is
invoked.
Compare start boundary-point of sourceRange to end
boundary-point of Range on which compareBoundaryPoints is
invoked.
Compare end boundary-point of sourceRange to end boundary-point
of Range on which compareBoundaryPoints is invoked.
Compare end boundary-point of sourceRange to start
boundary-point of Range on which compareBoundaryPoints is
invoked.
Compare the boundary-points of two Ranges in a document.
A code representing the type of comparison, as defined above.
The Range on which this current Range is compared to.
-1, 0 or 1 depending on whether the corresponding boundary-point of the
Range is respectively before, equal to, or after the corresponding boundary-point
of sourceRange.
WRONG_DOCUMENT_ERR: Raised if the two Ranges are not in the same Document or DocumentFragment.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Removes the contents of a Range from the containing document or document fragment without returning a reference to the removed content.
NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the content of the Range is read-only or any of the nodes that contain any of the content of the Range are read-only.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Moves the contents of a Range from the containing document or document fragment to a new DocumentFragment.
A DocumentFragment containing the extracted contents.
NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the content of the Range is read-only or any of the nodes which contain any of the content of the Range are read-only.
HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be extracted into the new DocumentFragment.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Duplicates the contents of a Range
A DocumentFragment that contains content equivalent to this Range.
HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be extracted into the new DocumentFragment.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Inserts a node into the Document or DocumentFragment at the start of the Range. If the container is a Text node, this will be split at the start of the Range (as if the Text node's splitText method was performed at the insertion point) and the insertion will occur between the two resulting Text nodes. Adjacent Text nodes will not be automatically merged. If the node to be inserted is a DocumentFragment node, the children will be inserted rather than the DocumentFragment node itself.
The node to insert at the start of the Range
NO_MODIFICATION_ALLOWED_ERR: Raised if an
WRONG_DOCUMENT_ERR: Raised if newNode and the
HIERARCHY_REQUEST_ERR: Raised if the newNode or
if newNode is an ancestor of the
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
INVALID_NODE_TYPE_ERR: Raised if newNode is an Attr, Entity,
Notation, or Document node.
Reparents the contents of the Range to the given node and inserts the node at the position of the start of the Range.
The node to surround the contents with.
NO_MODIFICATION_ALLOWED_ERR: Raised if an
WRONG_DOCUMENT_ERR: Raised if newParent and the
HIERARCHY_REQUEST_ERR: Raised if the newParent or
if newParent is an ancestor of the node would end up with
a child node of a type not allowed by the type of node.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
BAD_BOUNDARYPOINTS_ERR: Raised if the Range
INVALID_NODE_TYPE_ERR: Raised if node is an Attr, Entity,
DocumentType, Notation, Document, or DocumentFragment node.
Produces a new Range whose boundary-points are equal to the boundary-points of the Range.
The duplicated Range.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Returns the contents of a Range as a string. This string contains only the data characters, not any markup.
The contents of the Range.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
Called to indicate that the Range is no longer in use and that the
implementation may relinquish any resources associated with this Range.
Subsequent calls to any methods or attribute getters on this Range will result
in a DOMException being thrown with an error code of
INVALID_STATE_ERR.
INVALID_STATE_ERR: Raised if detach() has already been invoked
on this object.
This interface can be obtained from the object implementing
the Document interface using binding-specific casting methods.
The initial state of the Range returned from this method is such that both
of its boundary-points are positioned at the beginning of the corresponding
Document, before any content. The Range returned can only be used to select
content associated with this Document, or with DocumentFragments and Attrs for
which this Document is the ownerDocument.
Range operations may throw a RangeException as specified in
their method descriptions.
An integer indicating the type of error generated.
If the boundary-points of a Range do not meet specific requirements.
If the