我尝试使用输入获得当前选择的文本,window.getSelection()但我总是得到一个空字符串:
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。
getSelection不适用于在input元素中选择的文本,但不适用于在页面中对元素进行的选择。
getSelection
input
您可以使用selectionStart和selectionEnd这样的:
selectionStart
selectionEnd
return document.activeElement.value.substring( document.activeElement.selectionStart, document.activeElement.selectionEnd)
您可能应该为此创建一个函数,而不是单行代码。也许您还想然后测试是否document.activeElement确实是正确的元素类型,等等。当您使用它时,您甚至可以使其与IE9之前的浏览器兼容……([尽管很困难]
document.activeElement
简单功能
这也将工作的input或者textarea没有重点控制:
textarea
function getInputSelection(el) { if (el.selectionStart !== undefined) { return el.value.substring(el.selectionStart, el.selectionEnd); } } // Example call: console.log(getInputSelection(document.activeElement));
广泛的jQuery插件
这提供了更多的跨浏览器兼容性(pre- IE9),并且不仅支持以jQuery插件的形式获取,而且还支持选择范围和文本的设置。它处理一个事实,即CRLF字符序列以一种务实的方式算作一个字符位置(LF仅在原处替换):
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});