To improve this, I now need to examine the text before and after the selection, to see whether a tag has already been opened etc. Is there any simple way of checking whether the selection is a part of a larger node?
(Tags are opened [in HTML, with <
], but what you really mean is whether an element has been started. The difference is crucial for you to understand what you are doing here.)
Because a node in the document is part of the document tree, and a text node can be at most the child node of one non-text node, every text selection is "part of a larger node". However, whether you can find out what that node is, and whether it is easy to do depends both on your abilities and on the browser, as it depends on the DOM implementation used by the layout engine of the browser.
For example, in Gecko-based browsers such as Firefox and in WebCore-based browsers such as Chrome/Google Chrome, you could execute
var selection = window.getSelection();
on select. In selection
you would then have a reference to an object implementing the Selection
(Gecko) or DOMSelection
(WebCore) interface, that has properties such as anchorNode
that refer to an object implementing the Text
interface (see the Gecko DOM Reference at MDN for that).
That object, which represents the text node that the start of the selection is part of, has a parentNode
property which gets you the element node object, and through its tagName
or nodeName
property, the element type name:
var textParent = selection.anchorNode.parentNode;
var textParentType = textParent.nodeName;
The value of textParent.parentNode
can then be used to traverse one more level up the document tree aso.
Extra care must be taken when the anchorNode
and focusNode
properties refer to different text node objects, for then the selection usually spans not only several text nodes but several elements. That is, in a table the user could have easily selected the text "foobar" as in <td>foo</td><td>bar</td>
.
With runtime feature tests and exception handling you can determine which interface is supported without resorting to error-prone browser sniffing.
For example, if I was to select "jumps" in the following text and click, the correct behaviour would be to de-strong
it, as it is already in a strong
node.
You might want to reconsider that. Perhaps you just picked a bad example, but there can be value in a strong
element within a strong
element; the inner element's CSS properties are not necessarily redundant. Another example is emphasizing text already in an em
element for which the user might want to use the strong
element then.
Avoid jQuery; you do not need it and on closer inspection you would not even want it.