Soru Şu anda seçili metni alma


Şu anda seçilen metni kullanarak bir giriş elde etmeye çalışıyorum window.getSelection() ama her zaman boş bir dize alıyorum:

expect(browser.executeScript("return window.getSelection().toString();")).toEqual("test");

Sonuçlara göre:

Expected '' to equal 'test'.

Bir hedef site olarak angularjs.org kullanarak tam tekrarlanabilir test:

describe("My test", function () {
    beforeEach(function () {
        browser.get("https://angularjs.org/");
    });

    it("should select text in an input", function () {
        var query = element(by.css("input.search-query"));
        query.sendKeys("test");
        query.sendKeys(protractor.Key.chord(protractor.Key.COMMAND, "a"));

        expect(browser.executeScript("return window.getSelection().toString();")).toEqual("test");
    });
});

Aslında girilen metnin COMMAND + "a" ile seçildiğini görüyorum.

Neyi yanlış yapıyorum?

İtici kullanılarak 2.5.1, firefox 41.


17
2017-11-02 17:50


Menşei




Cevaplar:


getSelection seçilen metin için çalışmaz input öğeler, ancak sayfadaki öğeler üzerinde yapılan seçimler için.

Kullanabilirsin selectionStart ve selectionEnd bunun gibi:

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

Muhtemelen bu tek liner yerine bunun için bir fonksiyon yaratmalısınız. Ve belki de sonra test etmek istersiniz document.activeElement gerçekten doğru tipte bir elemantır, vb. Ve siz ona geldiğinizde, IE9 öncesi tarayıcılar için bile uyumlu hale getirebilirsiniz ...zor olsa da)

Basit fonksiyon

Bu da üzerinde çalışacak input veya textarea odaklanmayan kontroller:

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

Geniş jQuery Plug-in

Bu, daha fazla tarayıcılar arası uyumluluk sağlar (öncedenIE9) ve sadece almayı değil, aynı zamanda seçim aralığını ve metni de jQuery Eklenti. Aslında bununla ilgilenir CRLF Karakter dizileri pragmatik bir şekilde bir karakter pozisyonu olarak sayılır. LF bir tek):

/**
 * 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();
        }
    });
};

Örnek kullanım:

// Get
console.log($('textarea').selection().text);
// Set text
$('textarea').selection({text: "Hello!"});
// Set starting point of selection
$('textarea').selection({start: 1});

16
2017-11-02 18:09



Evet, sonunda neyle sonuçlandım? expect(browser.executeScript("return arguments[0].value.substring(arguments[0].selectionStart, arguments[0].selectionEnd);", query.getWebElement())).toEqual("test");. Teşekkür ederim! - alecxe
Bu özelliği bilmiyordum bile. Çok havalı! - Bobby Russell