最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Set textarea's caret position using x and y position - Stack Overflow

programmeradmin1浏览0评论

I want to implement inline edition, so if user clicks on a div with some text, the textarea will appear at the same position as clicked div's position and will get the text from the div. This is fine for me, but what I want to do next is to set textarea's caret position according to x and y position from div click event. Any ideas?

HTML:

<div id="content" style="display: block; z-index: 10">Some text</div>

<textarea id="editor" style="position: absolute; display: none; z-index: 11"></textarea>

JS:

$('#content').click(function(e) {
    var content = $(this);
    var editor = $('#editor');

    var position = content.offset();

    editor.css('left', position.left);
    editor.css('top', position.top);
    editor.val(content.text());
    editor.show();

    var mousePosition = { x: e.offsetX, y: e.offsetY };

    // here I want to set the #editor caret position at the same place,
    // where user clicks the #content (mousePosition variable)
});

I want to implement inline edition, so if user clicks on a div with some text, the textarea will appear at the same position as clicked div's position and will get the text from the div. This is fine for me, but what I want to do next is to set textarea's caret position according to x and y position from div click event. Any ideas?

HTML:

<div id="content" style="display: block; z-index: 10">Some text</div>

<textarea id="editor" style="position: absolute; display: none; z-index: 11"></textarea>

JS:

$('#content').click(function(e) {
    var content = $(this);
    var editor = $('#editor');

    var position = content.offset();

    editor.css('left', position.left);
    editor.css('top', position.top);
    editor.val(content.text());
    editor.show();

    var mousePosition = { x: e.offsetX, y: e.offsetY };

    // here I want to set the #editor caret position at the same place,
    // where user clicks the #content (mousePosition variable)
});
Share Improve this question edited Jul 31, 2013 at 9:18 cryss asked Jul 31, 2013 at 8:32 crysscryss 4,5291 gold badge33 silver badges36 bronze badges 6
  • 1 The caret is always positioned at a text node, you can't position it to an empty area. – Teemu Commented Jul 31, 2013 at 8:40
  • 1 The area won't be empty - it will have the same content as the div. – cryss Commented Jul 31, 2013 at 8:44
  • developer.mozilla/en-US/docs/Web/HTML/Content_Editable – Marcel Gwerder Commented Jul 31, 2013 at 8:45
  • I think that contenteditable feture will cause problems, when you use some binding tools like Knockout or angular. If you look at some popular task management tools like wunderlist. or asana. they don't use contenteditable. – cryss Commented Jul 31, 2013 at 8:57
  • Why these minuses? Something wrong with the question? – cryss Commented Jul 31, 2013 at 9:04
 |  Show 1 more ment

2 Answers 2

Reset to default 4

Looks like you could do something like this:

createTextArea = function (e) {
    var range = window.getSelection().getRangeAt(0),
        start = range.startOffset,
        target = e.target,
        setPoint;
    while (target.tagName.toLowerCase() !== 'div') {
        target = target.parentElement;
        if (!target) return;
    }
    range.setStart(target, 0);
    setPoint = range.toString().length;
    // place and show #editor
    editor.focus();
    editor.setSelectionRange(setPoint, setPoint);
    return;
};

An example at jsFiddle. Notice that this works only in modern browsers. Older IE's don't have Input API, and the Selection/Range model is totally different.

I've found a solution:

JS:

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.monAncestorContainer.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;
}

$.fn.selectRange = function (start, end) {
    if (!end) end = start;
    return this.each(function () {
        if (this.setSelectionRange) {
            this.focus();
            this.setSelectionRange(start, end);
        } else if (this.createTextRange) {
            var range = this.createTextRange();
            range.collapse(true);
            range.moveEnd('character', end);
            range.moveStart('character', start);
            range.select();
        }
    });
};

Usage:

$('#content').click(function (e) {
    var content = $(this);
    var editor = $('#editor');

    var caret = getCaretPosition(this);

    var position = content.offset();

    editor.css('left', position.left);
    editor.css('top', position.top);
    editor.val(content.text());
    editor.show();

    var mousePosition = { x: e.offsetX, y: e.offsetY };

    // here I want to set the #editor caret position at the same place,
    // where user clicks the #content (mousePosition variable)

    editor.selectRange(caret, caret);
});
发布评论

评论列表(0)

  1. 暂无评论