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

入力されたテキストがCOMMAND + "a"で選択されていることを確認します。

私は間違っていますか?分度器2.5.1を使用して

、Firefoxの41

答えて

16

getSelectioninput要素で選択したテキストのが、ページ全体の要素に行われた選択のために動作しません。あなたはこのようなselectionStartselectionEndを使用することができます

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

おそらく、この機能の代わりに、このワンライナーを作成する必要があります。そして、多分あなたは、その後もなど、document.activeElementは確か要素の右のタイプであるかどうかをテストしたいとあなたがそれであるときに、あなたも前IE9ブラウザ用の互換性になるかもしれない...(difficult though

シンプル機能

これがフォーカスを持っていないinputまたはtextareaコントロールでも動作します:

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プラグインの形式で設定することもサポートしています。

/** 
* 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

うん、ここに私がいることはCRLF文字列は実用的な方法(のみLFによってその場で交換してください)内の1つの文字位置と数えているという事実を扱います最終的には 'expect(browser.executeScript(" return arguments [0] .value.substring(arguments [0] .selectionStart、arguments [0] .selectionEnd); "、query.getWebElement()))となりました。 toEqual( "test"); '。ありがとうございました! – alecxe

+0

この機能について知りませんでした。とてもかっこいい! –

関連する問題