获取当前选定的文本 [英] Getting currently selected text
问题描述
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");
结果为:
Expected '' to equal 'test'.
使用angularjs.org作为目标站点的完整可重复测试:
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");
});
});
请注意,我实际上看到输入的文本是用COMMAND +"a"选中的.
Note that I actually see the entered text being selected with COMMAND + "a".
我在做什么错了?
使用量角器2.5.1,firefox 41.
Using protractor 2.5.1, firefox 41.
推荐答案
getSelection
不适用于在input
元素中选择的文本,但不适用于在页面中对元素进行的选择.
getSelection
does not work for text selected in input
elements, but for selections made on elements across the page.
您可以像这样使用selectionStart
和selectionEnd
:
return document.activeElement.value.substring(
document.activeElement.selectionStart,
document.activeElement.selectionEnd)
您可能应该为此创建一个函数,而不是单行代码.也许您还想然后测试document.activeElement
是否确实是正确的元素类型,等等.当您使用它时,甚至可以使其兼容IE9之前的浏览器...(
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)
简单功能
这也可以在没有焦点的input
或textarea
控件上使用:
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));
广泛的jQuery插件
这提供了更多的跨浏览器兼容性(-c8之前的版本),并且不仅支持以jQuery
插件的形式获取,而且还支持选择范围和文本的设置.它处理以下事实:CRLF
字符序列以务实的方式计为一个字符位置(仅由LF
代替):
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(/\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});
这篇关于获取当前选定的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!