Search code examples
javascriptjquerywysiwyg

finding <br> position in wysiwyg editor with window.getSelection


I am trying to develop a wysiwyg editör. In the editör, i am trying to find the position of "br" when onkeydown function fire.

<p><b>1234</b><br><br>678</p>

When i locate cursor near 6 getting 678 with "oSelection.anchorNode.nodeValue". When i locate cursot near "br" getting nothing.

i want to find before and after tag near cursor?


Solution

  • Update 2: After talking to ismail the question could be changed to: how to find out, whether the element before/after the cursor is a <br> tag. This can be achieved like this:

    var selection = window.getSelection(),
        isBRBeforeCursor = IsBRBeforeCursor(selection),
        isBRAfterCursor = IsBRAfterCursor(selection);
    
    function GetPreviousSibling(node) {
        if (node.previousSibling != null) {
            return node.previousSibling;
        } else if (node.parentNode != null) {
            return GetPreviousSibling(node.parentNode);
        } else {
            return null;
        }
    }
    
    function GetNextSibling(node) {
        if (node.nextSibling != null) {
            return node.nextSibling;
        } else if (node.parentNode != null) {
            return GetNextSibling(node.parentNode);
        } else {
            return null;
        }
    }
    
    function IsBRBeforeCursor(selection) {
        if(selection.anchorNode.nodeName === '#text') {
            if(selection.anchorOffset > 0) {
                // There is text before the cursor
                return false;
            } else {
                var previousSibling = GetPreviousSibling(selection.anchorNode);
                return previousSibling !== null && previousSibling.nodeName === 'BR';
            }
        } else {
            if(selection.anchorOffset > 0) {
                return selection.anchorNode.childNodes[selection.anchorOffset - 1].nodeName === 'BR';
            } else {
                var previousSibling = GetPreviousSibling(selection.anchorNode);
                return previousSibling !== null && previousSibling.nodeName === 'BR';
            }
        }
    }
    
    function IsBRAfterCursor(selection) {
        if(selection.anchorNode.nodeName === '#text') {
            if(selection.anchorOffset < selection.anchorNode.nodeValue.length) {
                // There is text after the cursor
                return false;
            } else {
                var nextSibling = GetNextSibling(selection.anchorNode);
                return nextSibling !== null && nextSibling.nodeName === 'BR';
            }
        } else {
            if(selection.anchorNode.childNodes.length > selection.anchorOffset) {
                return selection.anchorNode.childNodes[selection.anchorOffset].nodeName === 'BR';
            } else {
                var nextSibling = GetNextSibling(selection.anchorNode);
                return nextSibling !== null && nextSibling.nodeName === 'BR';
            }
        }
    }
    

    Update: I think it is a bit tricky to always find the correct previous/next element, because the text is a node itself. So to get the previous/next element, you need to go a level up sometimes before looking left and right. Have a look at the following example:

    <p><b>123</b><br><u><i><br>456</i></u><br></p>
    
    1. Cursor is between 1 and 2.

      The next element is <br>, which is one level up and then to the right.

    2. Cursor is between 4 and 5.

      The previous element is <br>, which is just one to the left. The next element is <br>, which is two levels up and then to the right.

    If this is the case, you can find the previous/next element like this:

    function getElementBeforeSelection() {
        var anchor = window.getSelection().anchorNode;
        while(anchor.previousSibling === null && anchor.nodeName != 'BODY') {
            anchor = anchor.parentNode;
        }
    
        return anchor.previousSibling;
    }
    

    Original answer: You can get to the surrounding elements with parentNode, previousSibling and nextSibling. So the tags before and after the cursor are:

    var anchorNode = window.getSelection().anchorNode,
        before = anchorNode.previousSibling,
        after = anchorNode.nextSibling;