How do I find out the DOM node at cursor in a browser's editable content window using Javascript?

I am looking for a solution that works cross browser i.e. IE, Firefox and Safari.

13.10.2009 22:59:09
2 ОТВЕТА
РЕШЕНИЕ

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;
        }   
    }
}
18
13.10.2009 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 13.10.2009 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="stackoverflow.com">xyz</a> if the caret was in between say 'x' and 'y', shouldn't parentElement() return the 'a' node?
Murali VP 13.10.2009 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 13.10.2009 23:51:32
The IE code is quite involved. I use my own optimizations of the algorithms in IERange (code.google.com/p/ierange).
Tim Down 14.10.2009 00:04:35
Still works for me in IE. Can you post an example showing your problem?
Tim Down 13.12.2009 23:21:44

You can also use the Rangy Library:

elementAtCursor = rangy.getSelection().anchorNode.parentNode
3
22.09.2017 19:44:23