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); 

我有两个function:

 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> 

这是一个jQuery解决scheme:

 $.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 
  • 的jsfiddle
  • JsBin

这里的解决scheme是正确的,除了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; }; 

我find了适合我的解决scheme:

 $.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; 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(); 

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

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

我使用这个: http : //plugins.jquery.com/project/jCaret

在将文本插入textarea之前设置焦点?

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

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

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

这在Chrome中适用于我

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

显然你需要延迟一微秒或更长的时间,因为通常用户通过点击文本字段中的某个位置(或者通过点击标签)来关注文本字段,所以您必须等到位置为止由用户点击设置,然后进行更改。

我意识到这是一个非常古老的post,但我认为我应该提供一个更简单的解决scheme来更新它只使用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); } }); 

我接受批评。 谢谢。

更新:这个解决scheme不允许正常的复制和粘贴function工作(即ctrl-c,ctrl-v),所以我将不得不在今后编辑这个,以确保部分再次工作。 如果你有一个想法如何做到这一点,请在这里发表评论,我会很高兴地testing出来。 谢谢。

对我在bitbucket中find的代码稍作修改

代码现在能够select/突出显示开始/结束点,如果给2个职位。 经过testing,并在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) 

基于这个问题 ,在textarea中有新行的时候,答案就不会对ie和opera有效。 答案解释了如何在调用setSelectionRange之前调整selectionStart,selectionEnd。

我已经从@AVProgrammer提出的解决scheme尝试另一个问题adjustOffset,它的工作。

 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); } 

只要记得在函数调用之后返回false,如果你使用箭头键,否则Chrome将会破裂。

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

如果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链接

我必须得到这个工作的contenteditable元素和jQuery和tought有人可能想要它准备使用:

 $.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)build立offeset并设置元素的焦点。

另外一个小提示,如果从控制台运行$(selector).setCaret(num) ,它将返回console.log,但是由于在控制台窗口中build立了焦点,所以不会显示焦点。

最好; D