获取当前选中的文本
我正在尝试使用 window.getSelection()
但我总是得到一个空字符串:
expect(browser.executeScript("return window.getSelection().toString();")).toEqual("test");
结果成:
预期 '' 等于 'test'.
使用 angularjs.org 作为目标站点的完整可重复测试:
describe("我的测试", function () {之前(函数(){browser.get("https://angularjs.org/");});it("应该在输入中选择文本", 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
元素中选择的文本,但适用于在整个页面.
您可以像这样使用 selectionStart
和 selectionEnd
:
return document.activeElement.value.substring(document.activeElement.selectionStart,document.activeElement.selectionEnd)
您可能应该为此创建一个函数,而不是这个单行.也许您还想测试 document.activeElement
是否确实是正确的元素类型等.当您使用它时,您甚至可以使其与 IE9 之前的浏览器兼容...(困难)p>
简单函数
这也适用于没有焦点的 input
或 textarea
控件:
函数 getInputSelection(el) {if (el.selectionStart !== undefined) {返回 el.value.substring(el.selectionStart, el.selectionEnd);}}//示例调用:console.log(getInputSelection(document.activeElement));
丰富的 jQuery 插件
这提供了更多的跨浏览器兼容性(IE9
之前),并且不仅支持获取,还支持以jQuery的形式设置选择范围和文本代码>插件.它以实用的方式处理
CRLF
字符序列计为一个字符位置的事实(仅用 LF
就地替换):
/*** 用于获取/设置选择范围和文本的 jQuery 插件* 在输入/文本区域元素中.设置好选择后,* 元素将获得焦点.得到选择时,* 某些浏览器要求元素具有焦点(IE8 及以下).* 如果需要,由调用者首先设置焦点.* @this {jQuery} 输入/文本区域元素.* @param {object} opt_bounds 提供时,它设置范围如下:* @param {number} opt_bounds.start 范围的可选开始.如果不* 提供,范围的起点不会改变.* @param {number} opt_bounds.end 范围的可选结束.如果不* 提供,范围的终点不会改变.如果为null,则结束* 的文本值是假定的.* @param {number} opt_bounds.text 要放入范围的可选文本.如果* 未提供,不会更改范围的文本.* @return {jQuery|object|undefined} 设置时:与@this 相同* 允许链接,当获取一个对象 {start, end, text, length}* 如果该信息表示第一个元素中的选择* 可用,否则未定义.*/$.fn.selection = 函数 (opt_bounds) {变量边界,输入范围,输入,文档范围,值;功能删除CR(S){//CRLF 在文本框中算一个单位,所以替换为 1 个字符//为了正确的偏移返回 s.replace(/
/g, '
');}如果(opt_bounds === 未定义){//得到如果(!this.length){返回;}边界 = {};输入=这个[0];如果(输入.setSelectionRange){//现代浏览器bounds.start = input.selectionStart;bounds.end = input.selectionEnd;} 别的 {//检查浏览器支持if (!document.selection || !document.selection.createRange) {返回;}//IE8 或更早版本docRange = document.selection.createRange();//选择必须仅限于输入if (!docRange || docRange.parentElement() !== input) { return;}//创建另一个只能在//输入边界.inputRange = input.createTextRange();inputRange.moveToBookmark(docRange.getBookmark());//测量我们可以在输入中返回多少个字符:bounds.start =-inputRange.moveStart('字符', -input.value.length);bounds.end = -inputRange.moveEnd('character', -input.value.length);}//添加属性:bounds.length = bounds.end - bounds.start;bounds.text = removeCR(input.value).substr(bounds.start, bounds.length);返回界限;}//放if (opt_bounds.text !== undefined) {opt_bounds.text = removeCR(opt_bounds.text);}返回 this.each(function () {bounds = $.extend($(this).selection(), opt_bounds);bounds.end = bounds.end === null ?this.value.length : bounds.end;if (opt_bounds.text !== undefined) {值 = removeCR(this.value);this.value = value.substr(0, bounds.start) + bounds.text +value.substr(bounds.end);bounds.end = bounds.start + bounds.text.length;}如果(this.setSelectionRange){//现代浏览器//调用 .focus() 以与 IE8 行为保持一致.//如果你不关心它,你可以忽略它.this.focus();this.setSelectionRange(bounds.start, bounds.end);} 否则如果(this.createTextRange){//IE8 及之前inputRange = this.createTextRange();inputRange.collapse(true);inputRange.moveEnd('字符', bounds.end);inputRange.moveStart('character', bounds.start);//.select() 也会聚焦元素:输入范围.select();}});};
使用示例:
//获取console.log($('textarea').selection().text);//设置文本$('textarea').selection({text: "Hello!"});//设置选择的起点$('textarea').selection({start: 1});
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("return window.getSelection().toString();")).toEqual("test");
Results into:
Expected '' to equal 'test'.
The complete reproducible test using angularjs.org as a target site:
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");
});
});
Note that I actually see the entered text being selected with COMMAND + "a".
What am I doing wrong?
Using protractor 2.5.1, firefox 41.
解决方案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(/
/g, '
');
}
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});
相关文章