Aaron Digulla
Aaron Digulla

Reputation: 328564

How can I get the DOM element which contains the current selection?

You can select a part of a web page with the mouse.

I know that I can get the currently selected text but how can I get the DOM element which contains the start or end of the current selection?

Upvotes: 43

Views: 46300

Answers (2)

Tim Down
Tim Down

Reputation: 324547

The following will return the container element of the start or end boundary of the current selection, using the boolean isStart to specify whether you want the start or end boundary. It will work in most mainstream browsers. Add feature tests for more robustness.

function getSelectionBoundaryElement(isStart) {
    var range, sel, container;
    if (document.selection) {
        range = document.selection.createRange();
        range.collapse(isStart);
        return range.parentElement();
    } else {
        sel = window.getSelection();
        if (sel.getRangeAt) {
            if (sel.rangeCount > 0) {
                range = sel.getRangeAt(0);
            }
        } else {
            // Old WebKit
            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[isStart ? "startContainer" : "endContainer"];

           // Check if the container is a text node and return its parent if so
           return container.nodeType === 3 ? container.parentNode : container;
        }   
    }
}

Upvotes: 61

InvisibleBacon
InvisibleBacon

Reputation: 3222

In IE, use document.selection.createRange().parentElement() and in real browsers use window.getSelection().getRangeAt(0).startContainer.parentNode. Something like this:

function getSelectedNode()
{
    if (document.selection)
        return document.selection.createRange().parentElement();
    else
    {
        var selection = window.getSelection();
        if (selection.rangeCount > 0)
            return selection.getRangeAt(0).startContainer.parentNode;
    }
}

Upvotes: 40

Related Questions