17

我嘗試使用window.getSelection()獲得在輸入​​當前選定的文本,但我總是得到一個空字符串:入門當前選中的文本

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

結果爲:

Expected '' to equal 'test'. 

的完成重複的測試使用angularjs.org作爲目標網站:

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

請注意,我在實際工作Y見正與COMMAND +選擇「A」輸入的文本。

我在做什麼錯?

用量角器2.5.1,Firefox的41

回答

16

getSelection不爲input元素中的文字工作,但由於在整個頁面元素做出的選擇。

你可以使用selectionStartselectionEnd這樣的:

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

你或許應該創建一個函數爲這個代替這一個班輪的。也許你想,然後還考document.activeElement是否確實元素等的權利類型,當你在這,你甚至可能會預IE9瀏覽器兼容...(difficult though

簡單功能

這也將工作在inputtextarea控件沒有焦點:

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

廣泛的jQuery插件

這提供了更多的跨瀏覽器兼容性(預IE9),並支持不僅獲得,而且還設置選擇範圍和文本,以jQuery插件的形式。它用事實交易,CRLF字符序列算一個字符位置,以務實的方式(就地由LF只能更換):

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

使用例:

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

是啊,這裏是我「VE終於結束了:'希望(browser.executeScript( 「返回參數[0] .value.substring(參數[0] .selectionStart,參數[0] .selectionEnd);」,query.getWebElement()))。 toEqual( 「測試」);'。謝謝! – alecxe

+0

甚至不知道這個功能。很酷! –