15.2 Converting a User Selection into an Arbitrary Element
NN n/a, IE 4(Win)
15.2.1 Problem
You want to wrap a
user's body text selection in an element to assign a
style that highlights the selection.
15.2.2 Solution
We begin with a paragraph container that processes a selection by way
of an onmouseup event handler:
<p onmouseup="selection2Element( )">Lorem ipsum dolor sit amet, consectetaur
adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p>
The selection2Element(
) event handler function creates an IE
TextRange object whose boundaries coincide with
the current selection, as reported by the browser the instant the
mouse button is released on the container:
function selection2Element( ) {
var rng = document.selection.createRange( );
var newHTML = "<span class='newSpan'>" + rng.text + "</span>";
rng.pasteHTML(newHTML);
}
It is assumed in this example that a style sheet rule for the
newSpan class name is already defined in the
document. The range's pasteHTML(
) method replaces the selection with new HTML, at which
time the text immediately gains the associated style properties. The
user sees nothing more than a style change of the selected text.
15.2.3 Discussion
Deploy this solution guardedly, as you can get yourself into
substantial trouble without realizing it. If a user drags a selection
across existing HTML container boundaries, the new HTML that the
selection2Element( ) function uses to replace the
selection will, at best, be ill-formed HTML that has containers
overlapping each other. At worst, the action will destroy the
document structure in the vicinity of the replacement.
One way to prevent such problems is to use the IE-only
onselectstart event handler in addition to
onmouseup. Script the
onselectstart event handler to invoke a function
that saves (in a global variable) a reference to the most recent
element in which the selection begins (derived from the
event.srcElement property). Then the
selection2Element( ) function compares its
event.srcElement property against the preserved
value. If they are the same, it means that the selection started and
ended in the same element:
// global
var selectionStart;
// invoked by onselectstart
function saveStart( ) {
selectionStart = event.srcElement;
}
// invoked by onmouseup
function selection2Element( ) {
if (event.srcElement = = selectionStart) {
var rng = document.selection.createRange( );
var newHTML = "<span class='newSpan'>" + rng.text + "</span>";
rng.pasteHTML(newHTML);
} else {
alert("Please restrict selections to within a single paragraph.");
}
}
One further simplification is to move the event handler assignments
to the body or document level, and assign the same class name to the
paragraphs containing selectable text. Then limit execution of the
inner statements of selection2Element( ) to those
event.srcElement objects whose
className property matches the class assignment.
The W3C DOM Range object, as implemented in the
Netscape browsers through Version 7, doesn't have
enough of the needed features to deploy this application.
15.2.4 See Also
Recipe 15.3 for a more advanced application of the IE
TextRange object.
|