如何使用jQuery设置文本字段中的光标位置?我有一个文本字段的内容,我希望用户的光标定位在一个特定的偏移时,他们聚焦在该字段。代码应该是这样的:

$('#input').focus(function() {
  $(this).setCursorPosition(4);
});

setCursorPosition函数的实现是什么样子的?如果您有一个内容为abcdefg的文本字段,此调用将导致游标定位如下:abcd**|**efg。

Java有一个类似的函数setCaretPosition。javascript中是否存在类似的方法?

更新:我修改了CMS的代码,以使用jQuery如下:

new function($) {
  $.fn.setCursorPosition = function(pos) {
    if (this.setSelectionRange) {
      this.setSelectionRange(pos, pos);
    } else if (this.createTextRange) {
      var range = this.createTextRange();
      range.collapse(true);
      if(pos < 0) {
        pos = $(this).val().length + pos;
      }
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  }
}(jQuery);

当前回答

对我在bitbucket中发现的代码做了小修改

如果给定2个位置,代码现在可以选择/突出起始/结束点。 经过测试,在FF/Chrome/IE9/Opera中工作良好。

$('#field').caret(1, 9);

代码如下所示,只有几行改动:

(function($) {
  $.fn.caret = function(pos) {
    var target = this[0];
    if (arguments.length == 0) { //get
      if (target.selectionStart) { //DOM
        var pos = target.selectionStart;
        return pos > 0 ? pos : 0;
      }
      else if (target.createTextRange) { //IE
        target.focus();
        var range = document.selection.createRange();
        if (range == null)
            return '0';
        var re = target.createTextRange();
        var rc = re.duplicate();
        re.moveToBookmark(range.getBookmark());
        rc.setEndPoint('EndToStart', re);
        return rc.text.length;
      }
      else return 0;
    }

    //set
    var pos_start = pos;
    var pos_end = pos;

    if (arguments.length > 1) {
        pos_end = arguments[1];
    }

    if (target.setSelectionRange) //DOM
      target.setSelectionRange(pos_start, pos_end);
    else if (target.createTextRange) { //IE
      var range = target.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos_end);
      range.moveStart('character', pos_start);
      range.select();
    }
  }
})(jQuery)

其他回答

对我在bitbucket中发现的代码做了小修改

如果给定2个位置,代码现在可以选择/突出起始/结束点。 经过测试,在FF/Chrome/IE9/Opera中工作良好。

$('#field').caret(1, 9);

代码如下所示,只有几行改动:

(function($) {
  $.fn.caret = function(pos) {
    var target = this[0];
    if (arguments.length == 0) { //get
      if (target.selectionStart) { //DOM
        var pos = target.selectionStart;
        return pos > 0 ? pos : 0;
      }
      else if (target.createTextRange) { //IE
        target.focus();
        var range = document.selection.createRange();
        if (range == null)
            return '0';
        var re = target.createTextRange();
        var rc = re.duplicate();
        re.moveToBookmark(range.getBookmark());
        rc.setEndPoint('EndToStart', re);
        return rc.text.length;
      }
      else return 0;
    }

    //set
    var pos_start = pos;
    var pos_end = pos;

    if (arguments.length > 1) {
        pos_end = arguments[1];
    }

    if (target.setSelectionRange) //DOM
      target.setSelectionRange(pos_start, pos_end);
    else if (target.createTextRange) { //IE
      var range = target.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos_end);
      range.moveStart('character', pos_start);
      range.select();
    }
  }
})(jQuery)

这适用于我在chrome

$('#input').focus(function() {
    setTimeout( function() {
        document.getElementById('input').selectionStart = 4;
        document.getElementById('input').selectionEnd = 4;
    }, 1);
});

显然,您需要一微秒或更长时间的延迟,因为通常用户通过单击文本字段中的某个位置(或通过单击tab)来关注您想要覆盖的文本字段,因此您必须等待用户单击设置的位置,然后更改它。

我知道这是一个非常老的帖子,但我认为我应该提供一个更简单的解决方案,只使用jQuery更新它。

function getTextCursorPosition(ele) {   
    return ele.prop("selectionStart");
}

function setTextCursorPosition(ele,pos) {
    ele.prop("selectionStart", pos + 1);
    ele.prop("selectionEnd", pos + 1);
}

function insertNewLine(text,cursorPos) {
    var firstSlice = text.slice(0,cursorPos);
    var secondSlice = text.slice(cursorPos);

    var new_text = [firstSlice,"\n",secondSlice].join('');

    return new_text;
}

使用ctrl-enter添加新行(就像在Facebook中):

$('textarea').on('keypress',function(e){
    if (e.keyCode == 13 && !e.ctrlKey) {
        e.preventDefault();
        //do something special here with just pressing Enter
    }else if (e.ctrlKey){
        //If the ctrl key was pressed with the Enter key,
        //then enter a new line break into the text
        var cursorPos = getTextCursorPosition($(this));                

        $(this).val(insertNewLine($(this).val(), cursorPos));
        setTextCursorPosition($(this), cursorPos);
    }
});

我乐于接受批评。谢谢你!

更新:这个解决方案不允许正常的复制和粘贴功能的工作(即ctrl-c, ctrl-v),所以我将不得不编辑这在未来,以确保该部分再次工作。如果你知道怎么做,请在这里评论,我很乐意测试。谢谢。

这里的解决方案是正确的,除了jQuery扩展代码。

扩展函数应该遍历每个选定的元素并返回此值以支持链接。以下是正确的版本:

$.fn.setCursorPosition = function(pos) {
  this.each(function(index, elem) {
    if (elem.setSelectionRange) {
      elem.setSelectionRange(pos, pos);
    } else if (elem.createTextRange) {
      var range = elem.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  });
  return this;
};

在IE中移动光标到某个位置这段代码就足够了:

var range = elt.createTextRange();
range.move('character', pos);
range.select();