Viliam
Viliam

Reputation: 4414

How to detect selection outside textarea and input

jQuery select event is limited to textarea and input:text only. Is there a way to handle a selection in ordinary elements such as <div>?

Upvotes: 2

Views: 1341

Answers (2)

Tim Down
Tim Down

Reputation: 324567

jQuery's select event wraps the native browser select event, which fires for any kind of selection in IE and WebKit but only for inputs and textareas in other browsers.

This question has come up several times before:

You'll see lots of answers similar to Luke's, none of which fully work. Firstly, you need to consider selections made by keyboard, and also via the "Select All" option in the Edit and context browser menus. Secondly, checking for a change in selection by looking at the selection text isn't entirely reliable: if the user selects the same text elsewhere in the document, it will not be picked up.

Here's some code that will fix most of the problems, although short of polling the selection there's nothing you can do about "Select All" from the Edit and context menus.

var addSelectHandler = function(callback) {
    var selectionChangeEventHandler;

    if (typeof window.getSelection != "undefined" && typeof document.addEventListener != "undefined") {
        var previouslySelected = null;

        var rangesEqual = function(r1, r2) {
            return r1.startContainer === r2.startContainer && r1.startOffset === r2.startOffset &&
                   r1.endContainer === r2.endContainer && r1.endOffset === r2.endOffset;
        };

        selectionChangeEventHandler = function() {
            var sel = window.getSelection(), selectedRanges = [], range;
            var changed = !previouslySelected || (sel.rangeCount != previouslySelected.length);
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                range = sel.getRangeAt(0).cloneRange();
                selectedRanges[i] = range;
                if (!changed && !rangesEqual(range, previouslySelected[i])) {
                    changed = true;
                }
            }
            previouslySelected = selectedRanges;
            if (changed) {
                callback();
            }
        };

        document.addEventListener("mouseup", selectionChangeEventHandler, false);
        document.addEventListener("keyup", selectionChangeEventHandler, false);
    } else if (typeof document.selection != "undefined" && typeof document.attachEvent != "undefined") {
        // This is IE, which fires a selectionchange event for any selection
        document.attachEvent("onselectionchange", callback);
    }
};

addSelectHandler(function() {
    alert("Selection changed");
}

Upvotes: 3

Luke
Luke

Reputation: 8407

function getSelText()
{
    var txt = '';
     if (window.getSelection)
    {
        txt = window.getSelection();
             }
    else if (document.getSelection)
    {
        txt = document.getSelection();
            }
    else if (document.selection)
    {
        txt = document.selection.createRange().text;
    }
    return txt;
}

$(document).mouseup(function() {
    alert(getSelText());
});

I dont know if jQuery has one but this can be used to make a new plugin, where you hook up an event for mouseup.

Upvotes: 2

Related Questions