admin管理员组文章数量:1129091
How do you set the cursor position in a text field using jQuery? I've got a text field with content, and I want the users cursor to be positioned at a certain offset when they focus on the field. The code should look kind of like this:
$('#input').focus(function() {
$(this).setCursorPosition(4);
});
What would the implementation of that setCursorPosition function look like? If you had a text field with the content abcdefg, this call would result in the cursor being positioned as follows: abcd**|**efg.
Java has a similar function, setCaretPosition. Does a similar method exist for javascript?
Update: I modified CMS's code to work with jQuery as follows:
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);
How do you set the cursor position in a text field using jQuery? I've got a text field with content, and I want the users cursor to be positioned at a certain offset when they focus on the field. The code should look kind of like this:
$('#input').focus(function() {
$(this).setCursorPosition(4);
});
What would the implementation of that setCursorPosition function look like? If you had a text field with the content abcdefg, this call would result in the cursor being positioned as follows: abcd**|**efg.
Java has a similar function, setCaretPosition. Does a similar method exist for javascript?
Update: I modified CMS's code to work with jQuery as follows:
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);
Share
Improve this question
edited Mar 20, 2014 at 13:05
Soul_man
5755 silver badges15 bronze badges
asked Jan 31, 2009 at 16:39
jcnnghmjcnnghm
7,4327 gold badges34 silver badges38 bronze badges
5
|
16 Answers
Reset to default 301Here's a jQuery solution:
$.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();
}
});
};
With this, you can do
$('#elem').selectRange(3,5); // select a range of text
$('#elem').selectRange(3); // set cursor position
- JsFiddle
- JsBin
I have two functions:
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);
}
Then you can use setCaretToPos like this:
setCaretToPos(document.getElementById("YOURINPUT"), 4);
Live example with both a textarea
and an input
, showing use from 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>
As of 2016, tested and working on Chrome, Firefox, IE11, even IE8 (see that last here; Stack Snippets don't support IE8).
The solutions here are right except for the jQuery extension code.
The extension function should iterate over each selected element and return this
to support chaining. Here is the a correct version:
$.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;
};
I found a solution that works for me:
$.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;
}
Now you can move the focus to the end of any element by calling:
$(element).focusEnd();
Or you specify the position.
$(element).setCursorPosition(3); // This will focus on the third character.
This worked for me on Safari 5 on Mac OSX, jQuery 1.4:
$("Selector")[elementIx].selectionStart = desiredStartPos;
$("Selector")[elementIx].selectionEnd = desiredEndPos;
I do realize that this is a very old post, but I thought that I should offer perhaps a simpler solution to update it using only 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;
}
Usage for using ctrl-enter to add a new line (like in 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);
}
});
I am open to critique. Thank you.
UPDATE: This solution does not allow normal copy and paste functionality to work (i.e. ctrl-c, ctrl-v), so I will have to edit this in the future to make sure that part works again. If you have an idea how to do that, please comment here, and I will be happy to test it out. Thanks.
In IE to move cursor on some position this code is enough:
var range = elt.createTextRange();
range.move('character', pos);
range.select();
I'm using this: http://plugins.jquery.com/project/jCaret
Set the focus before you have inserted the text into the textarea thus?
$("#comments").focus();
$("#comments").val(comments);
This works for me in chrome
$('#input').focus(function() {
setTimeout( function() {
document.getElementById('input').selectionStart = 4;
document.getElementById('input').selectionEnd = 4;
}, 1);
});
Apparently you need a delay of a microsecond or more, because usually a user focusses on the text field by clicking at some position in the text field (or by hitting tab) which you want to override, so you have to wait till the position is set by the user click and then change it.
Just remember to return false right after the function call if you're using the arrow keys since Chrome fricks the frack up otherwise.
{
document.getElementById('moveto3').setSelectionRange(3,3);
return false;
}
Based on this question, the answer will not work perfectly for ie and opera when there is new line in the textarea. The answer explain how to adjust the selectionStart, selectionEnd before calling setSelectionRange.
I have try the adjustOffset from the other question with the solution proposed by @AVProgrammer and it work.
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);
}
Small modification to the code I found in bitbucket
Code is now able to select/highlight with start/end points if given 2 positions. Tested and works fine in FF/Chrome/IE9/Opera.
$('#field').caret(1, 9);
The code is listed below, only a few lines changed:
(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)
I had to get this working for contenteditable elements and jQuery and tought someone might want it ready to use:
$.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;
};
Usage $(selector).getCaret()
returns the number offset and $(selector).setCaret(num)
establishes the offeset and sets focus on element.
Also a small tip, if you run $(selector).setCaret(num)
from console it will return the console.log but you won't visualize the focus since it is established at the console window.
Bests ;D
You can directly change the prototype if setSelectionRange does not exist.
(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 link
As for me here the most easily way to add text(Tab -> \t) in textarea by cursor position and save the focus on cursor:
$('#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);
}
});
本文标签: javascriptjQuery Set Cursor Position in Text AreaStack Overflow
版权声明:本文标题:javascript - jQuery Set Cursor Position in Text Area - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736692075a1947987.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
$(this).get(0).setSelectionRange)
? You do know that's exactly the same asthis.setSelectionRange
, only slower and harder to read, right? jQuery is doing literally nothing for you here. – bobince Commented Apr 26, 2010 at 10:37