1

I have a standard content editable div:

<div id="profileBody" class="customInputDiv" contentEditable='true' autocomplete="off"></div>

Basically I want to detect whereabouts the cursor is on a certain event (preferably code that works onclick, keydown or on button).

Something like this:
onkeydown - save caret position within the div, then set caret position.

This sounds slightly silly, but is required because on certain events I will be changing the content slightly and when doing the cursor position changes which is very annoying.

I hate doing questions without examples of what I've tried but if you read previous questions I've always provide what I've tried very detailed, just hit a dead end here!

function setCaret() {
    var el = document.getElementById("editable");
    var range = document.createRange();
    var sel = window.getSelection();
    range.setStart(el.childNodes[2], 5);
    range.collapse(true);
    sel.removeAllRanges();
    sel.addRange(range);
    el.focus();
}
​

Maybe a good way of parsing the data from window.getSelection();?

Found: http://jsfiddle.net/s5xAr/3/ But i dont want the -- just want it to get the caret position using a function and set it e.g.

getCaretPOS();
//do something
setCaretPOS();

This code will set it but getting it seems to be the issue..

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Lemex
  • 3,772
  • 14
  • 53
  • 87

1 Answers1

1

To get the caret position, use this function:

function getCaretPosition(editableDiv) {
    var caretPos = 0, containerEl = null, sel, range;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.rangeCount) {
            range = sel.getRangeAt(0);
            if (range.commonAncestorContainer.parentNode == editableDiv) {
                caretPos = range.endOffset;
            }
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        if (range.parentElement() == editableDiv) {
            var tempEl = document.createElement("span");
            editableDiv.insertBefore(tempEl, editableDiv.firstChild);
            var tempRange = range.duplicate();
            tempRange.moveToElementText(tempEl);
            tempRange.setEndPoint("EndToEnd", range);
            caretPos = tempRange.text.length;
        }
    }
    return caretPos;
}

This should work fine for most browsers (leaving IE, of course). You seem to have IE covered with you setCaret function.

That function was from another SO answer. Have a look at the comments as well.

Demo

Community
  • 1
  • 1
Some Guy
  • 15,854
  • 10
  • 58
  • 67
  • console.log($('#' + mainContent)[0].selectionStart); when doing that which returns undefined – Lemex Sep 03 '12 at 10:24
  • @LiamMcCann Oh, yeah, didn't realize this didn't work for `contenteditable`s. I'll see if I can find something for those. – Some Guy Sep 03 '12 at 10:28
  • @LiamMcCann [Rangy](http://code.google.com/p/rangy/) looks like a library that could help you. See if it does. – Some Guy Sep 03 '12 at 10:56
  • That function comes from an answer of mine, and has drawbacks. See http://stackoverflow.com/a/3976125/96100 – Tim Down Sep 08 '12 at 09:04