W3c range
Range is used to indicate the user's selection area. This selection area is defined by two boundary locations, and the location is composed of its container and offset, called container and offset. The following is a simple location example:
Copy codeThe Code is as follows:
<P> <span> text </span> ^ <span> text </span> </p>
^ Indicates a position, the container is the parent node p, and the offset is 1 relative to the parent node. Note that when the container is an element node, its Offset Unit is the node, that is, the number of subnodes that have been experienced from the first subnode of the container to the current location.
Correspondingly, container can also be a text node, then container is textnode, and offset is the number of UTF-16 characters from the textnode to the current position (meaning that the Chinese and English count is the same, not byte count ). For example
Copy codeThe Code is as follows:
<P> <span> text </span> <span> 01234 ^ 567 </span> </p>
In the preceding example, the container is the "01234567" text node, and the offset value is the number of characters that have elapsed since the first character of the text node reached the current position.
Ie range
For a brief introduction, please refer to msdn
There is no clear concept of container and offset in ie range, but the basic idea is the same as w3c range, which has the same expression ability. It can be divided into textrange and controlrange, and contains a series of methods.
Textrange is not a literal text, but a representation of the content of the user's selected region (the complete content can be obtained using htmlText). Most of the operations are based on text rather than dom tree nodes.
Controlrange literally indicates obtaining the Selection control. When some elements (div, img, object...) are editable, you can click it to select the entire element.
Obtain ie Standardization
From the above introduction, we can see that the w3c range is more standardized and clearer, and its container and offset concepts are more intuitive. When we need to operate on the dom node associated with the range, there is no doubt that container, offset is essential, while ie range does not display the methods for getting these two key variables. As mentioned earlier, ie range actually has the w3c range equivalent function, then, you can use the methods provided to export these two variables.
Get range objects:
Range objects can be obtained in two ways:
1. Obtain the range from the selected area. You can call this operation.
Copy codeThe Code is as follows:
Document. selection. createRange ()
The method returns the TextRange or ControlRange instance based on the current selection.
2. Create a range from the element, which can be called
Copy codeThe Code is as follows:
OControlRange = object. createControlRange ()
Js Code
OTextRange = object. createTextRange ()
The former can be called on the body and element, and the latter can be called on most elements. After the call, the range completely overwrites the call element. EquivalentMoveToElementText.
Textrange standardization:
First, we will introduce the following methods:
Collapse: overlay the end position to the start position (true) or overlay the start position to the end position (false) based on the parameter ).
ParentElement: Obtain the element nodes in the selected region. The following example shows how to obtain the span node after calling the node.
Copy codeThe Code is as follows:
<Span> character </span>
MoveToElementText (Node a): Change the selected region to a, and the starting position is before and after a, as shown in the following span Node:
Copy codeThe Code is as follows:
^ <Span> text </span> ^
Range1.compareEndPoints ('xxtoyy', range2): xx, yy can be Start or End. Compare the xx position of range1 with the yy position of range2, and return, 0 indicates coincidence.
Range1.setEndPoint ("XxToYy", range2): xx, yy can be Start or End, set xx of range1 to yy of range2.
Conversion:
With the above five methods, we can start to standardize the first step: Get the location, first give the operation example:
(The Green block indicates the text node. Note: two adjacent text nodes are not displayed when the page is manually written. splitText is used for forced separation)
When we select the region collapse, there may be four locations: 1, 2, 3, 4, and 1 adjacent element nodes are the simplest:
1, 4 Location standardization:
1. Obtain the node p containing the position based on parentElement, that is, the container of the position.
2. verify that all element subnodes of the container are adjacent to known locations one by one. The verification method is to create a range package subnode through moveToElementText, then, use compareEndPoints to compare whether the front and back positions of the new range overlap with the current position:
Copy codeThe Code is as follows:
Range = range. duplicate ();
Range. collapse (start );
Var parent = range. parentElement (),
Siblings = parent. childNodes;
For (var I = 0; I <siblings. length; I ++ ){
Var child = siblings [I];
If (child. nodeType = 1 ){
Var tr = range. duplicate ();
Tr. moveToElementText (child );
// Start position comparison of child element nodes
Var comparisonStart = tr. compareEndPoints ('startstart', range ),
// Subelement node end position comparison
ComparisonEnd = tr. compareEndPoints ('endstart', range );
// The start is behind the current position and there is no need to continue the comparison
If (comparisonStart> 0) break;
Else if (! ComparisonStart | comparisonEnd = 1 & comparisonStart =-1) return {
Container: parent,
Offset: I
};
Else if (! ComparisonEnd) return {
Container: parent,
Offset: I + 1
};
}
}
2, 3 location standardization:
2 indicates that the location is between two text nodes, and the container is p. Because moveToElementText cannot act on the text node, you can only try another method.
3 indicates that the position is in the middle of the text node. At this time, the container is the text node, while the offset is the number of characters.
1. Stop when 1 is reached.
2. create a new range ra with the start position 1 and the end position 2 or 3. obtain all the characters ra_textlength of the ra. For each text node starting from position 1 to the right, subtract the length (data. length). When ra_textlength is 0, it indicates that the current position is 2, and the number of currently passed text nodes is offset.
When ra_textlength is negative, it indicates that the current position is 3, the current text node is the container of position 3, and the previous value of ra_textlength is offset.
Example:
Copy codeThe Code is as follows:
<P id = "test"> <strong> bold </strong> normal | text <I> italic </I> </p>
<Script>
Document. getElementById ("test"). childNodes [1]. splitText (2 );
</Script>
Standardized demo
Controlrange Standardization
Controlrange is very simple. The item (index) method gets the selected element and uses its parentNode to get the standardized representation.
PS: Reading the range of input boxes
Because the selection area of the input box is separated from the page selection area, the selection area of the input box has different acquisition methods (IE is basically the same ).