在满足要素中的标记式自动完成和插入/光标移动

jim*_*meh 10 javascript caret contenteditable

我正在研究一个jQuery插件,它允许你做@username样式标签,就像Facebook在状态更新输入框中做的那样.

我的问题是,即使经过数小时的研究和实验,简单地移动插入符号似乎也很难.我已经设法<a>用某个人的名字注入标签,但是把它放在它之后似乎是火箭科学,特别是如果它应该在所有浏览器中都可以使用.

我还没有考虑用@username标签替换打字的文本,而不是像我现在正在做的那样注入... lol

关于在Stack Overflow上使用contenteditable的问题有很多问题,我想我已经阅读了所有这些问题,但它们并没有真正涵盖我需要的内容.所以任何人都可以提供的信息会很棒:)

Tim*_*own 5

你可以使用我的Rangy库,它试图成功地规范化浏览器范围和选择实现.如果你已经设法插入了<a>你所说的并且你已经在一个名为的变量中插入了它aElement,你可以执行以下操作:

var range = rangy.createRange();
range.setStartAfter(aElement);
range.collapse(true);
var sel = rangy.getSelection();
sel.removeAllRanges();
sel.addRange(range);
Run Code Online (Sandbox Code Playgroud)


Nic*_*rns 1

正如您所说,您已经可以在插入符号处插入标签,我将从那里开始。首先要做的就是在插入标签时为其指定一个 id。然后你应该有这样的东西:

<div contenteditable='true' id='status'>I went shopping with <a href='#' id='atagid'>Jane</a></div>

这是一个应将光标放置在标签后面的函数。

function setCursorAfterA()
{
    var atag = document.getElementById("atagid");
    var parentdiv = document.getElementById("status");
    var range,selection;
    if(window.getSelection) //FF,Chrome,Opera,Safari,IE9+
    {
        parentdiv.appendChild(document.createTextNode(""));//FF wont allow cursor to be placed directly between <a> tag and the end of the div, so a space is added at the end (this can be trimmed later)
        range = document.createRange();//create range object (like an invisible selection)
        range.setEndAfter(atag);//set end of range selection to just after the <a> tag
        range.setStartAfter(atag);//set start of range selection to just after the <a> tag
        selection = window.getSelection();//get selection object (list of current selections/ranges)
        selection.removeAllRanges();//remove any current selections (FF can have more than one)
        parentdiv.focus();//Focuses contenteditable div (necessary for opera)
        selection.addRange(range);//add our range object to the selection list (make our range visible)
    }
    else if(document.selection)//IE 8 and lower
    { 
        range = document.body.createRange();//create a "Text Range" object (like an invisible selection)
        range.moveToElementText(atag);//select the contents of the a tag (i.e. "Jane")
        range.collapse(false);//collapse selection to end of range (between "e" and "</a>").
        while(range.parentElement() == atag)//while ranges cursor is still inside <a> tag
        {
             range.move("character",1);//move cursor 1 character to the right
        }
        range.move("character",-1);//move cursor 1 character to the left
        range.select()//move the actual cursor to the position of the ranges cursor
    }
    /*OPTIONAL: 
    atag.id = ""; //remove id from a tag
    */
}
Run Code Online (Sandbox Code Playgroud)

编辑: 经过测试和修复的脚本。它绝对适用于 IE6、chrome 8、firefox 4 和 opera 11。手头没有其他浏览器可供测试,但它不使用最近更改的任何功能,因此它应该适用于任何支持 contenteditable 的浏览器。

这个按钮对于测试来说很方便: <input type='button' onclick='setCursorAfterA()' value='Place Cursor After &lt;a/&gt; tag' >

尼科