jQuery: invoking a function after a user has selected text (text selection callback)

jQuery: invoking a function after a user has selected text (text selection callback)

Handling text selection with jQuery so that we can invoke a callback function just after a user has selected text.

Selecting text on a page is quite a trivial task for a user, but not so trivial is the correct handling of this action from a JavaScript/jQuery perspective. Specifically, the model that controls such an action is supported in one way by all of the most used standard-compliant web browsers and in another, radically different way by Internet Explorer (at the moment of this writing, IE8 is still widely adopted by web users and, what's worse, its JavaScript support is actually far from being standard-compliant). For that reason, if we want to execute our code just after a user has selected some text, we have to write two distinct routines. Let's see the details.

A selection occurs when a user releases the mouse button on a text string or, if he uses the keyboard, when he releases a key after pressing it with his finger.

Therefore we have to use both the mouseup and keyup events attached to the global document object. Handling the selection itself, instead, relies on the correct handling of the two ways by which browsers handle text selection. More precisely, standard compliant browsers use window.getSelection() whereas IE implements document.selection.

Here's our code:

function selectCallback(selectionParentElement) {
    alert('Text selected on the ' + selectionParentElement.nodeName.toLowerCase() + ' element');

}

var mouseOrKeyUpHandler;

if (typeof window.getSelection != "undefined") {
    // Non-IE
    mouseOrKeyUpHandler = function() {
        var sel = window.getSelection();
        if (sel.rangeCount > 0) {
            var range = sel.getRangeAt(0);
            if (range.toString()) {
                var selParentEl = range.commonAncestorContainer;
                if (selParentEl.nodeType == 3) {
                    selParentEl = selParentEl.parentNode;
                }
                selectCallback(selParentEl);
            }
        }
    };
} else if (typeof document.selection != "undefined") {
    // IE
    mouseOrKeyUpHandler = function() {
        var sel = document.selection;
        if (sel.type == "Text") {
            var textRange = sel.createRange();
            if (textRange.text != "") {
                selectCallback(textRange.parentElement());
            }
        }
    };
}

$(document).bind('mouseup', mouseOrKeyUpHandler);
$(document).bind('keyup', mouseOrKeyUpHandler);

Our callback function, our action (so to speak) works on the DOM element where the selection occurs. In this example I've used a dummy alert box, but if you recall correctly, jQuery has the ability to turn a DOM element into a jQuery element by using the $() wrapper:

function selectCallback(selectionParentElement) {
    
    var $element = $(selectionParentElement); // jQuery element

}

In other words, you can bind any kind of actions to the callback function invoked at the end of a text selection. You can see the demo below.

Demo

Live demo