Question

Hello all you ridiculously genius people!

So I'm creating a basic word processor, and I need to have an option to clear formatting in a certain section. The place the user is typing is split up into several different divs, and whenever they hit enter it starts a new div. When they add a style option (Bold, italics, etc.) it ads the correct html tag.

Well, I want the user to be able to clear all formatting on text they highlight. To do this, I need to find the element that all of them share. so if it displayed "Here is my text" in a structure like this:

<div id="1">
    <div>Here</div>
    <div>is</div>
    <div>some</div>
    <div>text</div>
</div>

and the user highlighted all 4 words, I would need to computer to give me the div with the id "1" because that is what they all share in common.

I am completely stumped on this, and have absolutely no clue where to start, so I really don't have any code for you. I will be using window.getSelected(); to get the actual text, but I have no idea how to go about finding the divs around it.

Thanks for your help!

Was it helpful?

Solution

If you are using window.getSelection(), it returns a selection object which contains properties .anchorNode and .focusNode which are the nodes at the start and end of the selection. You can then use those nodes to walk up the parent chain to find any level of parent you want.

The closest common parent could be found by getting the immediate parent of the first object and then seeing if it is also a parent of the second object. If not, go up one parent higher until you eventually find a common parent.

function findCommonParentElement(startNode, endNode) {

    // see if node has a particular parent 
    // by walking up the parent chain and comparing parents
    function hasParent(node, parent) {
        while (node && node !== parent && node !== document.body) {
            node = node.parentNode;
        }
        return node === parent;
    }

    // for text nodes, get the containing element
    // for elements, just return what was passed in
    function getElement(node) {
        while (node && node.nodeType !== 1) {
            node = node.parentNode;
        }
        return node;
    }

    // go up the parent chain of endNode looking for a node 
    // that startNode has as a parent    
    while (endNode && !hasParent(startNode, endNode)) {
        endNode = endNode.parentNode;
    }
    // return the containing element - so it won't return a textnode
    return getElement(endNode);
}

// Usage:
var sel = window.getSelection();
var commonParent = findCommonParentElement(sel.anchorNode, sel.focusNode);

Working demo: http://jsfiddle.net/jfriend00/GV96w/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top