Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/477.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Javascript移动光标位置?_Javascript_Contenteditable_Caret - Fatal编程技术网

使用Javascript移动光标位置?

使用Javascript移动光标位置?,javascript,contenteditable,caret,Javascript,Contenteditable,Caret,我希望将插入符号移动到其当前位置的正前方四个空格,以便可以正确插入制表符。我已经在插入符号的位置插入了HTML,但是当我插入HTML时,插入符号就被留下了。在过去的一个多小时里,我一直在寻找各种方法来实现这一点,我已经尝试了很多,但我无法让它们中的任何一种为我工作。以下是我尝试过的最新方法: function moveCaret(input, distance) { if(input.setSelectionRange) { input.focus();

我希望将插入符号移动到其当前位置的正前方四个空格,以便可以正确插入制表符。我已经在插入符号的位置插入了HTML,但是当我插入HTML时,插入符号就被留下了。在过去的一个多小时里,我一直在寻找各种方法来实现这一点,我已经尝试了很多,但我无法让它们中的任何一种为我工作。以下是我尝试过的最新方法:

function moveCaret(input, distance) {
    if(input.setSelectionRange) {
        input.focus();
        input.setSelectionRange(distance, distance);
    } else if(input.createTextRange) {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd(distance);
        range.moveStart(distance);
        range.select();
    }
}
它完全不做任何事情——不移动插入符号,不抛出任何错误或任何东西。这让我感到困惑。是的,我知道上面的方法集(应该)将插入符号设置在指定节点开始的某个位置(即,
input
),但即使这样也不起作用。那么,我到底做错了什么,我怎样才能做对呢


编辑:根据o.v.提供的链接,我成功地拼凑了一些东西,最终做了一些事情:抛出一个错误。耶!以下是新代码:

this.moveCaret = function(distance) {
    if(that.win.getSelection) {
        var range = that.win.getSelection().getRangeAt(0);
        range.setStart(range.startOffset + distance);
    } else if (that.win.document.selection) {
        var range = that.win.document.selection.createRange();
        range.setStart(range.startOffset + distance);
    }
}

现在,这给出了错误
未捕获错误:未找到\u错误:DOM异常8
。你知道为什么吗?

你的代码片段是用于文本输入和文本区域,而不是
contenteditable
元素

如果您的所有内容都在一个文本节点中,并且所选内容完全包含在其中,那么以下内容将在所有主要浏览器中使用,包括IE 6

演示:

代码:

函数moveCaret(win,charCount){
var-sel,范围;
if(win.getSelection){
//IE9+和其他浏览器
sel=win.getSelection();
如果(选择范围计数>0){
var textNode=sel.focusNode;
var newOffset=sel.focusOffset+charCount;
选择折叠(textNode,Math.min(textNode.length,newOffset));
}
}else if((sel=win.document.selection)){

//IE是否尝试设置
元素。selectionStart
元素。selectionEnd
?据我所知,它应该可以跨浏览器用于输入和文本区域。我之所以避免使用它,是因为我相信它在早期版本的IE8中不起作用。不过,我还是会看看它。我测试的唯一IE版本是IE9,最好的是luck尽管如此。:)是的,它似乎在早期版本的IE中不起作用,但无论如何还是要感谢。=)可能的重复:和答案似乎得到了很多认可。+1因为它是一段非常有用的代码。只是一个问题:为什么要通过win参数访问全局?但是如果需要转到在上一个文本节点中,此操作失败,原因是
sel.focusNode
==0@danm07:您想要什么样的解释?范围和选择方法是标准的,并且有很好的文档记录。代码简短。此外,如果您想用注释对其进行注释,您也可以这样做。我认为唯一有用的注释是标签用于两个主要代码分支(IE9+和其他浏览器,IE6-8)。给出预先制定的解决方案在填补知识空白方面效果甚微。如果你能指出发问者代码中的错误,那就太好了,我很确定这是一种礼节。@danm07:在成百上千的答案中,我对此感到内疚。我不认为在所有代码中添加连续注释是普遍做法;我不确定r我认为应该是这样。更多的手牵手是否会鼓励或阻止人们查找我在这里使用的浏览器API?我不知道。无论如何,我在这个答案中添加了一些细节。
function moveCaret(win, charCount) {
    var sel, range;
    if (win.getSelection) {
        // IE9+ and other browsers
        sel = win.getSelection();
        if (sel.rangeCount > 0) {
            var textNode = sel.focusNode;
            var newOffset = sel.focusOffset + charCount;
            sel.collapse(textNode, Math.min(textNode.length, newOffset));
        }
    } else if ( (sel = win.document.selection) ) {
        // IE <= 8
        if (sel.type != "Control") {
            range = sel.createRange();
            range.move("character", charCount);
            range.select();
        }
    }
}