I am looking for a solution that works cross browser i.e. IE, Firefox and Safari.
views:
490answers:
1
Q:
How do I find out the DOM node at cursor in a browser's editable content window using Javascript?
+5
A:
By "editable content window" I'm going to assume you mean an element with contenteditable
turned on or a document with designMode
turned on.
There are also two cases to consider: the case when the user has made a selection and the case where there is just a caret. The code below will work in both cases, and will give you the innermost element that completely contains the selection. If the selection is completely contained within a text node it's slightly complicated to get that text node in IE (trivial in other browsers), so I haven't provided that code here. If you need it, I can dig it out.
function getSelectionContainerElement() {
var range, sel, container;
if (document.selection && document.selection.createRange) {
// IE case
range = document.selection.createRange();
return range.parentElement();
} else if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt) {
if (sel.rangeCount > 0) {
range = sel.getRangeAt(0);
}
} else {
// Old WebKit selection object has no getRangeAt, so
// create a range from other selection properties
range = document.createRange();
range.setStart(sel.anchorNode, sel.anchorOffset);
range.setEnd(sel.focusNode, sel.focusOffset);
// Handle the case when the selection was selected backwards (from the end to the start in the document)
if (range.collapsed !== sel.isCollapsed) {
range.setStart(sel.focusNode, sel.focusOffset);
range.setEnd(sel.anchorNode, sel.anchorOffset);
}
}
if (range) {
container = range.commonAncestorContainer;
// Check if the container is a text node and return its parent if so
return container.nodeType === 3 ? container.parentNode : container;
}
}
}
Tim Down
2009-10-13 23:22:24
Tim, this is exactly what I was looking for. I would appreciate if you can also dig in the IE case where selection is contained with in a text node. Thanks.
Murali VP
2009-10-13 23:28:00
Btw, the IE case where you return range.parentElement() always seems to return the body element even though the caret was in text that inside an anchor node eg. In this HTML <a href="http://www.stackoverflow.com">xyz</a> if the caret was in between say 'x' and 'y', shouldn't parentElement() return the 'a' node?
Murali VP
2009-10-13 23:44:57
Yes, it should. I haven't had problems with `parentElement()` before - have you got a page I can look at showing the problem?
Tim Down
2009-10-13 23:51:32
The IE code is quite involved. I use my own optimizations of the algorithms in IERange (http://code.google.com/p/ierange/).
Tim Down
2009-10-14 00:04:35
@Tim, great code. But there is a problem with IE when you want to get the parent without selecting any text, just positioning a caret. How to fix that?
markiz
2009-12-12 12:35:50
Still works for me in IE. Can you post an example showing your problem?
Tim Down
2009-12-13 23:21:44