jQuery设置文本区域的光标位置

如何使用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);
363997 次浏览

我有两个功能:

function setSelectionRange(input, selectionStart, selectionEnd) {
if (input.setSelectionRange) {
input.focus();
input.setSelectionRange(selectionStart, selectionEnd);
}
else if (input.createTextRange) {
var range = input.createTextRange();
range.collapse(true);
range.moveEnd('character', selectionEnd);
range.moveStart('character', selectionStart);
range.select();
}
}


function setCaretToPos (input, pos) {
setSelectionRange(input, pos, pos);
}

然后你可以像这样使用setCaretToPos:

setCaretToPos(document.getElementById("YOURINPUT"), 4);

使用textareainput的实例,展示了jQuery的用法:

function setSelectionRange(input, selectionStart, selectionEnd) {
if (input.setSelectionRange) {
input.focus();
input.setSelectionRange(selectionStart, selectionEnd);
} else if (input.createTextRange) {
var range = input.createTextRange();
range.collapse(true);
range.moveEnd('character', selectionEnd);
range.moveStart('character', selectionStart);
range.select();
}
}


function setCaretToPos(input, pos) {
setSelectionRange(input, pos, pos);
}


$("#set-textarea").click(function() {
setCaretToPos($("#the-textarea")[0], 10)
});
$("#set-input").click(function() {
setCaretToPos($("#the-input")[0], 10);
});
<textarea id="the-textarea" cols="40" rows="4">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</textarea>
<br><input type="button" id="set-textarea" value="Set in textarea">
<br><input id="the-input" type="text" size="40" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit">
<br><input type="button" id="set-input" value="Set in input">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

截至2016年,在Chrome, Firefox, IE11,甚至IE8上进行测试和工作(参见最后的在这里;堆栈片段不支持IE8)。

下面是一个jQuery解决方案:

$.fn.selectRange = function(start, end) {
if(end === undefined) {
end = start;
}
return this.each(function() {
if('selectionStart' in this) {
this.selectionStart = start;
this.selectionEnd = end;
} else if(this.setSelectionRange) {
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();
}
});
};

有了这个,你就可以了

$('#elem').selectRange(3,5); // select a range of text
$('#elem').selectRange(3); // set cursor position

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

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

这适用于我的Safari 5在Mac OSX, jQuery 1.4:

$("Selector")[elementIx].selectionStart = desiredStartPos;
$("Selector")[elementIx].selectionEnd = desiredEndPos;

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

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

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

只要记住在函数调用后返回false,如果你使用方向键,因为Chrome fricks frack否则。

{
document.getElementById('moveto3').setSelectionRange(3,3);
return false;
}

我找到了一个适合我的解决方案:

$.fn.setCursorPosition = function(position){
if(this.length == 0) return this;
return $(this).setSelection(position, position);
}


$.fn.setSelection = function(selectionStart, selectionEnd) {
if(this.length == 0) return this;
var input = this[0];


if (input.createTextRange) {
var range = input.createTextRange();
range.collapse(true);
range.moveEnd('character', selectionEnd);
range.moveStart('character', selectionStart);
range.select();
} else if (input.setSelectionRange) {
input.focus();
input.setSelectionRange(selectionStart, selectionEnd);
}


return this;
}


$.fn.focusEnd = function(){
this.setCursorPosition(this.val().length);
return this;
}

现在你可以通过调用以下命令将焦点移动到任何元素的末尾:

$(element).focusEnd();

或者你指定位置。

$(element).setCursorPosition(3); // This will focus on the third character.

如果setSelectionRange不存在,您可以直接更改原型。

(function() {
if (!HTMLInputElement.prototype.setSelectionRange) {
HTMLInputElement.prototype.setSelectionRange = function(start, end) {
if (this.createTextRange) {
var range = this.createTextRange();
this.collapse(true);
this.moveEnd('character', end);
this.moveStart('character', start);
this.select();
}
}
}
})();
document.getElementById("input_tag").setSelectionRange(6, 7);

jsFiddle链接

基于问题,当文本区域中有新行时,答案将不能完美地用于ie和opera。 回答解释了如何在调用setSelectionRange之前调整selectionStart, selectionEnd

我已经尝试了调整偏移从其他问题的解决方案由@AVProgrammer和它的工作。

function adjustOffset(el, offset) {
/* From https://stackoverflow.com/a/8928945/611741 */
var val = el.value, newOffset = offset;
if (val.indexOf("\r\n") > -1) {
var matches = val.replace(/\r\n/g, "\n").slice(0, offset).match(/\n/g);
newOffset += matches ? matches.length : 0;
}
return newOffset;
}


$.fn.setCursorPosition = function(position){
/* From https://stackoverflow.com/a/7180862/611741 */
if(this.lengh == 0) return this;
return $(this).setSelection(position, position);
}


$.fn.setSelection = function(selectionStart, selectionEnd) {
/* From https://stackoverflow.com/a/7180862/611741
modified to fit https://stackoverflow.com/a/8928945/611741 */
if(this.lengh == 0) return this;
input = this[0];


if (input.createTextRange) {
var range = input.createTextRange();
range.collapse(true);
range.moveEnd('character', selectionEnd);
range.moveStart('character', selectionStart);
range.select();
} else if (input.setSelectionRange) {
input.focus();
selectionStart = adjustOffset(input, selectionStart);
selectionEnd = adjustOffset(input, selectionEnd);
input.setSelectionRange(selectionStart, selectionEnd);
}


return this;
}


$.fn.focusEnd = function(){
/* From https://stackoverflow.com/a/7180862/611741 */
this.setCursorPosition(this.val().length);
}

对我在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)

设置焦点之前,你已经插入文本到文本区,从而?

$("#comments").focus();
$("#comments").val(comments);

这适用于我在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.getCaret = function(n) {
var d = $(this)[0];
var s, r;
r = document.createRange();
r.selectNodeContents(d);
s = window.getSelection();
console.log('position: '+s.anchorOffset+' of '+s.anchorNode.textContent.length);
return s.anchorOffset;
};


$.fn.setCaret = function(n) {
var d = $(this)[0];
d.focus();
var r = document.createRange();
var s = window.getSelection();
r.setStart(d.childNodes[0], n);
r.collapse(true);
s.removeAllRanges();
s.addRange(r);
console.log('position: '+s.anchorOffset+' of '+s.anchorNode.textContent.length);
return this;
};

使用$(selector).getCaret()返回数字偏移量,$(selector).setCaret(num)建立偏移量并将焦点设置在元素上。

还有一个小提示,如果你从控制台运行$(selector).setCaret(num),它会返回console.log,但你不会看到焦点,因为它是在控制台窗口建立的。

D最好成绩;

对于我来说,这里最简单的添加文本的方法(Tab ->\t)在文本区域通过光标位置并保存光标的焦点:

$('#text').keyup(function () {
var cursor = $('#text').prop('selectionStart');
//if cursot is first in textarea
if (cursor == 0) {
//i will add tab in line
$('#text').val('\t' + $('#text').val());
//here we set the cursor position
$('#text').prop('selectionEnd', 1);
} else {
var value = $('#text').val();
//save the value before cursor current position
var valToCur = value.substring(0, cursor);
//save the value after cursor current position
var valAfter = value.substring(cursor, value.length);
//save the new value with added tab in text
$('#text').val(valToCur + '\t' + valAfter);
//set focus of cursot after insert text (1 = because I add only one symbol)
$('#text').prop('selectionEnd', cursor + 1);
}
});