Reputation: 763
I'm working on a Chrome extension that deals with text selection. I want to detect whether the selected text is editable. Given a Selection object returned by getSelection(), is it possible to check whether the selected text is editable? How?
Upvotes: 1
Views: 2056
Reputation: 287990
A selection can contain text from multiple elements. Some elements may be editable and some may not.
However, if you are only interested in the element where the selection starts, you can use
Selection.prototype.anchorNode
, which returns the Node
in which the selection begins.Node.prototype.parentNode
, which should be the Element
in which the selection begins. Latest browsers also support Node.prototype.parentElement
.HTMLElement.prototype.isContentEditable
, a read-only property returns a Boolean that is true
if the contents of the element are editable; otherwise it returns false
.That is:
getSelection().anchorNode.parentNode.isContentEditable
However, that won't work for input
and textarea
elements because:
getSelection()
won't return selections in them, because their value doesn't exist as a text node. You can use document.activeElement
instead.isContentEditable
won't apply because you edit their value instead of their content. Instead, you should check if they are disabled
or readOnly
(disabled
ones doesn't seem to be selectable, but you can check just in case).function isEditable() {
var el = document.activeElement; // focused element
if(el && ~['input','textarea'].indexOf(el.tagName.toLowerCase())
return !el.readOnly && !el.disabled;
el = getSelection().anchorNode; // selected node
if(!el) return undefined; // no selected node
el = el.parentNode; // selected element
return el.isContentEditable;
}
var el;
function isEditable() {
if(el) el.className = '';
el = document.activeElement; // focused element
if(el && ~['input','textarea'].indexOf(el.tagName.toLowerCase())) {
el.className = 'selected';
return !el.readOnly && !el.disabled;
}
el = getSelection().anchorNode; // selected node
if(!el) return undefined; // no selected node
el = el.parentNode; // selected element
el.className = 'selected';
return el.isContentEditable;
}
var res = document.getElementById('result');
setInterval(function() {
res.textContent = isEditable();
}, 200);
#result {
font-size: 200%;
font-weight: bold;
}
.selected {
outline: 3px solid red;
}
<div>Non-editable div</div>
<div contentEditable="true">Editable div</div>
<input value="Editable input" />
<input value="Read-only input" readonly />
<input value="Disabled input" disabled />
<textarea>Editable textarea</textarea>
<textarea readonly>Read-only textarea</textarea>
<textarea disabled>Disabled textarea</textarea>
<hr />
<p>Is editable: <span id="result"></span></p>
Upvotes: 2
Reputation: 647
Input tags have the attribute readonly
to tell if the input can be edited.
You can try:
if(yourInput.readonly == true) { // where yourInput is the input tag
// can not be edited
} else {
// can be edited
}
You can tinker with this to fit what you are using.
Upvotes: 0