Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tinymce - Is it possible to get caret position of textarea corresponding to WYSIWYG Editor?

I'm wondering if we can get the real caret position of textarea when the fake cursor is in certain position under WYSIWYG Editor?

To better understand the question, please see the image below

enter image description here Under WYSIWYG mode, when the cursor is after s, we get position 53. and when the cursor is after t, we get position 79.

The code would be something like...

function getRealCaretPosition() {
    // all the dirty work goes here
}

// Ctrl + Q
if(e.ctrlKey && e.which == 81) {
    var pos = getRealCaretPosition();
    alert(pos);
}

Is this possible to be achieved, in theory?

like image 678
user1643156 Avatar asked Nov 03 '22 04:11

user1643156


1 Answers

window.getSelection() will give you the current selection point, then from here treewalk backwards until the start of your node, adding lengths of all text nodes encountered.

function walkback(node, stopAt) {
    if (node.childNodes && node.childNodes.length) { // go to last child
        while (node && node.childNodes.length > 0) {
            node = node.childNodes[node.childNodes.length - 1];
        }
    } else if (node.previousSibling) { // else go to previous node
        node = node.previousSibling;
    } else if (node.parentNode) { // else go to previous branch
        while (node && !node.previousSibling && node.parentNode) {
            node = node.parentNode;
        }
        if (node === stopAt) return;
        node = node.previousSibling;
    } else { // nowhere to go
        return;
    }
    if (node) {
        if (node.nodeType === 3) return node;
        if (node === stopAt) return;
        return walkback(node, stopAt);
    }
    return;
}

function getRealCaretPosition() {
    var sel = window.getSelection(), // current selection
        pos = sel.anchorOffset, // get caret start position
        node = sel.anchorNode; // get the current #text node
    while (node = walkback(node, myContentEditableElement)) {
        pos = pos + node.data.length; // add the lengths of the previous text nodes
    }
    return pos;
}

You will need to check that the current selection is actually within your HTMLElement of interest too, of course.

like image 187
Paul S. Avatar answered Nov 08 '22 06:11

Paul S.