Getting currently selected text

后端 未结 1 592
感动是毒
感动是毒 2021-01-01 14:57

I\'m try to get the currently selected text in an input using window.getSelection() but I\'m always getting an empty string:

expect(browser.executeScript(\"r         


        
相关标签:
1条回答
  • 2021-01-01 15:33

    getSelection does not work for text selected in input elements, but for selections made on elements across the page.

    You could use selectionStart and selectionEnd like this:

    return document.activeElement.value.substring(
       document.activeElement.selectionStart,
       document.activeElement.selectionEnd)
    

    You should probably create a function for this instead of this one-liner. And maybe you want to then also test whether document.activeElement is indeed the right type of element, etc. And when you are at it, you might even make it compatible for pre-IE9 browsers... (difficult though)

    Simple Function

    This will work also on input or textarea controls that do not have focus:

    function getInputSelection(el) {
        if (el.selectionStart !== undefined) {
            return el.value.substring(el.selectionStart, el.selectionEnd);
        }
    }
    // Example call:
    console.log(getInputSelection(document.activeElement));
    

    Extensive jQuery Plug-in

    This provides for more cross-browser compatibility (pre-IE9), and supports not only getting, but also setting the selection range and text, in the form of a jQuery plug-in. It deals with the fact that CRLF character sequences count as one character position in a pragmatic way (replace in-place by LF only):

    /**
     * jQuery plug-in for getting/setting the selection range and text  
     *   within input/textarea element(s). When the selection is set,
     *   the element will receive focus. When getting the selection,
     *   some browsers require the element to have focus (IE8 and below).
     *   It is up to the caller to set the focus first, if so needed.
     * @this {jQuery} Input/textarea element(s).
     * @param {object} opt_bounds When provided, it sets the range as follows:
     * @param {number} opt_bounds.start Optional start of the range. If not
     *   provided, the start point of the range is not altered.
     * @param {number} opt_bounds.end Optional end of the range. If not
     *   provided, the end point of the range is not altered. If null, the end
     *   of the text value is assumed.
     * @param {number} opt_bounds.text Optional text to put in the range. If
     *   not provided, no change will be made to the range's text.
     * @return {jQuery|object|undefined} When setting: the same as @this to 
     *   allow chaining, when getting, an object {start, end, text, length} 
     *   representing the selection in the first element if that info
     *   is available, undefined otherwise.
     */
    $.fn.selection = function (opt_bounds) {
        var bounds, inputRange, input, docRange, value;
    
        function removeCR(s) {
            // CRLF counts as one unit in text box, so replace with 1 char 
            // for correct offsetting
            return s.replace(/\r\n/g, '\n');
        }
    
        if (opt_bounds === undefined) {
            // Get 
            if (!this.length) {
                return;
            }
            bounds = {};
            input = this[0];
            if (input.setSelectionRange) {
                // Modern browsers
                bounds.start = input.selectionStart;
                bounds.end = input.selectionEnd;
            } else {
                // Check browser support
                if (!document.selection || !document.selection.createRange) {
                    return;
                }
                // IE8 or older
                docRange = document.selection.createRange();
                // Selection must be confined to input only
                if (!docRange || docRange.parentElement() !== input) { return; }
                // Create another range that can only extend within the
                // input boundaries.
                inputRange = input.createTextRange();
                inputRange.moveToBookmark(docRange.getBookmark());
                // Measure how many characters we can go back within the input:
                bounds.start =
                    -inputRange.moveStart('character', -input.value.length);
                bounds.end = -inputRange.moveEnd('character', -input.value.length);
            }
            // Add properties:
            bounds.length = bounds.end - bounds.start;
            bounds.text = removeCR(input.value).
                substr(bounds.start, bounds.length);
            return bounds;
        }
        // Set
        if (opt_bounds.text !== undefined) {
            opt_bounds.text = removeCR(opt_bounds.text);
        }
        return this.each(function () {
            bounds = $.extend($(this).selection(), opt_bounds);
            bounds.end = bounds.end === null ? this.value.length : bounds.end;
            if (opt_bounds.text !== undefined) {
                value = removeCR(this.value);
                this.value = value.substr(0, bounds.start) + bounds.text +
                    value.substr(bounds.end);
                bounds.end = bounds.start + bounds.text.length;
            }
            if (this.setSelectionRange) {
                // Modern browsers
                // Call .focus() to align with IE8 behaviour.
                // You can leave that out if you don't care about that.
                this.focus();
                this.setSelectionRange(bounds.start, bounds.end);
            } else if (this.createTextRange) {
                // IE8 and before
                inputRange = this.createTextRange();
                inputRange.collapse(true);
                inputRange.moveEnd('character', bounds.end);
                inputRange.moveStart('character', bounds.start);
                // .select() will also focus the element:
                inputRange.select();
            }
        });
    };
    

    Example use:

    // Get
    console.log($('textarea').selection().text);
    // Set text
    $('textarea').selection({text: "Hello!"});
    // Set starting point of selection
    $('textarea').selection({start: 1});
    
    0 讨论(0)
提交回复
热议问题