Ответ 1
getSelection
не работает для текста, выбранного в элементах input
, но для выбора, сделанного для элементов на странице.
Вы можете использовать selectionStart
и selectionEnd
следующим образом:
return document.activeElement.value.substring(
document.activeElement.selectionStart,
document.activeElement.selectionEnd)
Вероятно, вы должны создать для этого функцию вместо этого однострочного. И, возможно, вы захотите также проверить, действительно ли document.activeElement
правильный тип элемента и т.д. И когда вы на нем, вы даже можете сделать его совместимым для браузеров pre-IE9... (сложно, хотя)
Простая функция
Это будет работать и на элементах управления 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
Это обеспечивает большую совместимость между браузерами (pre- 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 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});