I'd like to get the selected text from a website, but when I use document.getSelection
it does not work for selections inside textareas and to get the selection from a text area I would need to know which textarea has the selection to use the textarea functions. Is there a simple methods for getting the current selection or do I need to iterate over all elements to test if they contain selected text?
Selection of text in general document content and in user input elements are mutually exclusive.
HTMLTextAreaElement and HTMLInputElement both have selectionStart
and selectionEnd
properties which are offsets of selected text in their content
INPUT elements which don't support selection return null
for the selection start/end properties.
If selectionStart
and selectionEnd
have the same value there is no selection within the element, and if the values are numeric it give the position of the cursor in the element.
If you click elsewhere on the page, INPUT and TEXTAREA elements lose focus and and any selected text in their content is deselected.
document.activeElement
holds a reference to the currently focused element. A null
value indicates the user has clicked outside web page content in the browser, possibly to change tabs. The tagName
property of a non-null activeElement
indicates what kind of element it is in upper case.
Putting all of this together I would start with a function similar to that below - it returns null if the page if the not in focus or an INPUT element that doesn't support selection is in focus. Otherwise it returns one of two types of object: either a selection object or a custom object containing details of user input with a type
property set to "UIText".
function getCurrentSelection() {
let selection;
const active = document.activeElement;
if(!active) return null;
let tagName = active.tagName;
if( tagName == "INPUT" || tagName == "TEXTAREA") {
const {selectionStart, selectionEnd} = active;
selection = selectionStart === null ? null : {
type: "UIText",
element: active,
tag: tagName,
selectionStart,
selectionEnd,
text: active.value.substring(selectionStart, selectionEnd)
};
}
else {
selection = document.getSelection()
}
return selection;
}