开发者

How to detect selection outside textarea and input

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


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:

  • Selected text event trigger in Javascript
  • Can I get a Javascript event from the selection of text outside of text or textarea?

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");
}


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜