使用JavaScript将光标放置在文本输入元素的文本末尾

什么是最好的方法(我假设最简单的方法),以放置光标在文本的输入文本元素的末尾通过JavaScript -焦点已设置到元素?

418405 次浏览
我在IE中遇到了同样的问题(通过RJS/prototype设置焦点后)。 当该字段已经有一个值时,Firefox已经在末尾留下了光标。IE将光标强制移到文本开头

我得出的解决方案如下:

<input id="search" type="text" value="mycurrtext" size="30"
onfocus="this.value = this.value;" name="search"/>

这在IE7和FF3 但在现代浏览器中不起作用中都有效(见注释),因为没有指定UA必须覆盖这种情况下的值(根据元政策编辑)。

在这之后,我发现最好的方法是使用setSelectionRange函数,如果浏览器支持它;如果不是,则恢复使用Mike Berrow回答中的方法(即将值替换为本身)。

我还将scrollTop设置为一个较高的值,以防我们处于可垂直滚动的textarea中。(在Firefox和Chrome中,使用任意的高值似乎比$(this).height()更可靠。)

我已经把它作为一个jQuery插件。(如果你没有使用jQuery,我相信你仍然可以很容易地得到主旨。)

我在IE6, IE7, IE8, Firefox 3.5.5,谷歌Chrome 3.0, Safari 4.0.4, Opera 10.00中进行了测试。

它可以在jquery.com上以PutCursorAtEnd插件的形式获得。为方便起见,1.0版的代码如下:

// jQuery plugin: PutCursorAtEnd 1.0
// http://plugins.jquery.com/project/PutCursorAtEnd
// by teedyay
//
// Puts the cursor at the end of a textbox/ textarea


// codesnippet: 691e18b1-f4f9-41b4-8fe8-bc8ee51b48d4
(function($)
{
jQuery.fn.putCursorAtEnd = function()
{
return this.each(function()
{
$(this).focus()


// If this function exists...
if (this.setSelectionRange)
{
// ... then use it
// (Doesn't work in IE)


// Double the length because Opera is inconsistent about whether a carriage return is one character or two. Sigh.
var len = $(this).val().length * 2;
this.setSelectionRange(len, len);
}
else
{
// ... otherwise replace the contents with itself
// (Doesn't work in Google Chrome)
$(this).val($(this).val());
}


// Scroll to the bottom, in case we're in a tall textarea
// (Necessary for Firefox and Google Chrome)
this.scrollTop = 999999;
});
};
})(jQuery);

试试这个,它对我很有效:

//input is the input element


input.focus(); //sets focus to element
var val = this.input.value; //store the value of the element
this.input.value = ''; //clear the value of the element
this.input.value = val; //set that value back.

为了让光标移动到最后,输入必须先有焦点,然后当值改变时,它才会移动到最后。如果你将.value设置为相同的值,它在chrome中不会改变。

在jQuery中,这是

$(document).ready(function () {
$('input').focus(function () {
$(this).attr('value',$(this).attr('value'));
}
}

如果输入字段只需要一个静态默认值,我通常用jQuery这样做:

$('#input').focus().val('Default value');

这似乎在所有浏览器中都有效。

仍然需要中间变量,(参见var val=) 否则光标的行为很奇怪,我们需要它在结尾
<body onload="document.getElementById('userinput').focus();">
<form>
<input id="userinput" onfocus="var val=this.value; this.value=''; this.value= val;"
class=large type="text" size="10" maxlength="50" value="beans" name="myinput">
</form>
</body>

我以前尝试过这些建议,但没有一个对我有效(在Chrome中测试了它们),所以我写了自己的代码-它在Firefox, IE, Safari, Chrome中工作得很好……

在文本区域:

onfocus() = sendCursorToEnd(this);

在Javascript中:

function sendCursorToEnd(obj) {
var value = obj.value; //store the value of the element
var message = "";
if (value != "") {
message = value + "\n";
};
$(obj).focus().val(message);}

设置光标时,点击文本区域的文本结束… 这段代码的变体是…也工作!对于Firefox, IE, Safari, Chrome..

在服务器端代码中:

txtAddNoteMessage.Attributes.Add("onClick", "sendCursorToEnd('" & txtAddNoteMessage.ClientID & "');")

在Javascript中:

function sendCursorToEnd(obj) {
var value =  $(obj).val(); //store the value of the element
var message = "";
if (value != "") {
message = value + "\n";
};
$(obj).focus().val(message);
$(obj).unbind();
}
<script type="text/javascript">
function SetEnd(txt) {
if (txt.createTextRange) {
//IE
var FieldRange = txt.createTextRange();
FieldRange.moveStart('character', txt.value.length);
FieldRange.collapse();
FieldRange.select();
}
else {
//Firefox and Opera
txt.focus();
var length = txt.value.length;
txt.setSelectionRange(length, length);
}
}
</script>

我在IE9和Firefox 6中使用了这个功能。和Opera 11.x

我刚刚发现,在iOS中,设置textarea.textContent属性将每次将光标放在textarea元素的文本末尾。这种行为是我的应用程序中的一个bug,但似乎是你可以故意使用的东西。

我已经尝试了以下相当大的成功在chrome

$("input.focus").focus(function () {
var val = this.value,
$this = $(this);
$this.val("");


setTimeout(function () {
$this.val(val);
}, 1);
});

简单介绍一下:

它获取每个带有类焦点的输入字段,然后将输入字段的旧值存储在一个变量中,然后将空字符串应用于输入字段。

然后等待1毫秒,再次输入旧值。

input = $('input');
input.focus().val(input.val()+'.');
if (input.val()) {input.attr('value', input.val().substr(0,input.val().length-1));}

好吧,我只用:

$("#myElement").val($("#myElement").val());

有一个简单的方法让它在大多数浏览器中工作。

this.selectionStart = this.selectionEnd = this.value.length;

然而,由于一些浏览器的特性,一个更全面的答案是这样的

setTimeout(function(){ that.selectionStart = that.selectionEnd = 10000; }, 0);

使用jQuery (设置监听器,否则没有必要)

$('#el').focus(function(){
var that = this;
setTimeout(function(){ that.selectionStart = that.selectionEnd = 10000; }, 0);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id='el' type='text' value='put cursor at end'>

使用Vanilla JS (借用addEvent函数from this answer)

// Basic cross browser addEvent
function addEvent(elem, event, fn){
if(elem.addEventListener){
elem.addEventListener(event, fn, false);
}else{
elem.attachEvent("on" + event,
function(){ return(fn.call(elem, window.event)); });
}}
var element = document.getElementById('el');


addEvent(element,'focus',function(){
var that = this;
setTimeout(function(){ that.selectionStart = that.selectionEnd = 10000; }, 0);
});
<input id='el' type='text' value='put cursor at end'>


Quirks

Chrome has an odd quirk where the focus event fires before the cursor is moved into the field; which screws my simple solution up. Two options to fix this:

  1. You can add a timeout of 0 ms (to defer the operation until the stack is clear)
  2. You can change the event from focus to mouseup. This would be pretty annoying for the user unless you still kept track of focus. I'm not really in love with either of these options.

Also, @vladkras pointed out that some older versions of Opera incorrectly calculate the length when it has spaces. For this you can use a huge number that should be larger than your string.

这是我的答案的jsFiddle演示。演示使用CoffeeScript,但如果需要,也可以使用将其转换为纯JavaScript

JavaScript中重要的部分是:

var endIndex = textField.value.length;
if (textField.setSelectionRange) {
textField.setSelectionRange(endIndex, endIndex);
}

我把这个答案贴出来是因为我已经为有同样问题的其他人写过了。这个答案不像上面的答案那样涵盖那么多的边缘情况,但它适合我,并且有一个jsFiddle演示可以玩。

下面是来自jsFiddle的代码,所以即使jsFiddle消失了,这个答案也会被保留:

moveCursorToEnd = (textField) ->
endIndex = textField.value.length
if textField.setSelectionRange
textField.setSelectionRange(endIndex, endIndex)


jQuery ->
$('.that-field').on 'click', ->
moveCursorToEnd(this)
<div class="field">
<label for="pressure">Blood pressure</label>:
<input class="that-field" type="text" name="pressure" id="pressure" value="24">
</div>
<p>
Try clicking in the text field. The cursor will always jump to the end.
</p>
body {
margin: 1em;
}


.field {
margin-bottom: 1em;
}

适用于所有浏览器和所有情况:

function moveCursorToEnd(el) {
window.setTimeout(function () {
if (typeof el.selectionStart == "number") {
el.selectionStart = el.selectionEnd = el.value.length;
} else if (typeof el.createTextRange != "undefined") {
var range = el.createTextRange();
range.collapse(false);
range.select();
}
}, 1);
}

如果您需要从onFocus事件处理程序移动光标,需要超时

试试下面的代码:

$('input').focus(function () {
$(this).val($(this).val());
}).focus()

简单。在编辑或更改值时,首先放置焦点,然后设置值。

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

这个问题很有趣。最令人困惑的是,我没有找到完全解决这个问题的方法。

+++++++解决方案+++++++

  1. 你需要一个JS函数,像这样:

    function moveCursorToEnd(obj) {
    
    
    if (!(obj.updating)) {
    obj.updating = true;
    var oldValue = obj.value;
    obj.value = '';
    setTimeout(function(){ obj.value = oldValue; obj.updating = false; }, 100);
    }
    
    
    }
    
  2. You need to call this guy in the onfocus and onclick events.

    <input type="text" value="Test Field" onfocus="moveCursorToEnd(this)" onclick="moveCursorToEnd(this)">
    

IT WORKS ON ALL DEVICES AN BROWSERS!!!!

var valsrch = $('#search').val();
$('#search').val('').focus().val(valsrch);

拿出一些答案。制作单行jquery。

$('#search').focus().val($('#search').val());

虽然这可能是一个有很多答案的老问题,但我遇到过一个类似的问题,没有一个答案是我想要的,或者解释得很糟糕。selectionStart和selectionEnd属性的问题是,它们不存在输入类型number(虽然这个问题是关于文本类型的,但我认为这可能会帮助那些可能有其他需要关注的输入类型的人)。所以如果你不知道函数关注的输入类型是否是类型号,你就不能使用这个解决方案。

跨浏览器和所有输入类型的解决方案相当简单:

  • 获取输入值并将其存储在变量中
  • 关注输入
  • 将输入值设置为存储值

这样光标就在输入元素的末尾。
所以你所要做的就是这样(使用jquery,提供一个人希望关注的元素选择器是通过点击元素的“data-focus-element”数据属性和函数在点击后执行)。foo的元素):< / p >

$('.foo').click(function() {
element_selector = $(this).attr('data-focus-element');
$focus = $(element_selector);
value = $focus.val();
$focus.focus();
$focus.val(value);
});

为什么会这样?简单地说,当调用.focus()时,焦点将被添加到输入元素的开头(这是这里的核心问题),忽略了输入元素中已经有一个值的事实。但是,当输入的值被改变时,光标会自动放在输入元素中值的末尾。因此,如果你用之前在输入中输入的相同值重写这个值,这个值看起来不会动,但是光标会移动到末尾。

如果先设置值,再设置焦点,光标将始终出现在最后。

$("#search-button").click(function (event) {
event.preventDefault();
$('#textbox').val('this');
$("#textbox").focus();
return false;
});

这是要测试的小提琴 https://jsfiddle.net/5on50caf/1/ < / p >

我喜欢接受的答案很多,但它停止工作在Chrome。在Chrome浏览器中,光标要走到最后,需要改变输入值。解决方法如下:

<input id="search" type="text" value="mycurrtext" size="30"
onfocus="var value = this.value; this.value = null; this.value = value;" name="search"/>

我想把光标放在“div”元素的末尾,其中contentteditable = true,我用Xeoncross代码得到了一个解决方案:

<input type="button" value="Paste HTML" onclick="document.getElementById('test').focus(); pasteHtmlAtCaret('<b>INSERTED</b>'); ">


<div id="test" contenteditable="true">
Here is some nice text
</div>

这个函数很神奇:

 function pasteHtmlAtCaret(html) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();


// Range.createContextualFragment() would be useful here but is
// non-standard and not supported in all browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);


// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
document.selection.createRange().pasteHTML(html);
}
}

适用于大多数浏览器,请检查,这段代码将文本和焦点放在div元素(不是输入元素)文本的末尾

https://jsfiddle.net/Xeoncross/4tUDk/

谢谢,Xeoncross

虽然我回答的太晚了,但对于以后的查询,这将是有帮助的。并且它也可以在contenteditable div中工作。

从你需要在最后设置焦点的地方;写这段代码-

var el = document.getElementById("your_element_id");
placeCaretAtEnd(el);

函数是-

function placeCaretAtEnd(el) {
el.focus();
if (typeof window.getSelection != "undefined"
&& typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}

我也面临着同样的问题。这个终于对我有用了

jQuery.fn.putCursorAtEnd =  = function() {


return this.each(function() {


// Cache references
var $el = $(this),
el = this;


// Only focus if input isn't already
if (!$el.is(":focus")) {
$el.focus();
}


// If this function exists... (IE 9+)
if (el.setSelectionRange) {


// Double the length because Opera is inconsistent about whether a carriage return is one character or two.
var len = $el.val().length * 2;


// Timeout seems to be required for Blink
setTimeout(function() {
el.setSelectionRange(len, len);
}, 1);


} else {


// As a fallback, replace the contents with itself
// Doesn't work in Chrome, but Chrome supports setSelectionRange
$el.val($el.val());


}


// Scroll to the bottom, in case we're in a tall textarea
// (Necessary for Firefox and Chrome)
this.scrollTop = 999999;


});


};

我们可以这样称呼它:

var searchInput = $("#searchInputOrTextarea");


searchInput
.putCursorAtEnd() // should be chainable
.on("focus", function() { // could be on any event
searchInput.putCursorAtEnd()
});

它适用于safari, IE, Chrome, Mozilla。在移动设备上,我没有尝试过这种方法。

检查这个解决方案!

//fn setCurPosition
$.fn.setCurPosition = function(pos) {
this.focus();
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;
};


// USAGE - Set Cursor ends
$('#str1').setCurPosition($('#str1').val().length);


// USAGE - Set Cursor at 7 position
// $('#str2').setCurPosition(7);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Set cursor at any position</p>
<p><input type="text" id="str1" value="my string here" /></p>
<p><input type="text" id="str2" value="my string here" /></p>

现在是2019年,上面的方法对我来说都没用,但这个方法管用,取自https://css-tricks.com/snippets/javascript/move-cursor-to-end-of-input/

function moveCursorToEnd(id) {
var el = document.getElementById(id)
el.focus()
if (typeof el.selectionStart == "number") {
el.selectionStart = el.selectionEnd = el.value.length;
} else if (typeof el.createTextRange != "undefined") {
var range = el.createTextRange();
range.collapse(false);
range.select();
}
}
<input id="myinput" type="text" />
<a href="#" onclick="moveCursorToEnd('myinput')">Move cursor to end</a>

el.setSelectionRange(-1, -1);

< a href = " https://codesandbox。io / s / peaceful-bash-x2mti noreferrer“rel = > https://codesandbox.io/s/peaceful-bash-x2mti < / >

这个方法更新HTMLInputElement。selectionStart selectionEnd, 和selectionDirection属性一次调用

https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange

在其他js方法中,-1通常表示(到)最后一个字符。这也是这种情况,但我在文档中找不到明确提到的这种行为。

超级简单(你可能需要关注input元素)

inputEl = getElementById('inputId');
var temp = inputEl.value;
inputEl.value = '';
inputEl.value = temp;

尝试使用Vanilla JavaScript。

<input type="text" id="yourId" onfocus="let value = this.value; this.value = null; this.value=value" name="nameYouWant" class="yourClass" value="yourValue" placeholder="yourPlaceholder...">

在Js

document.getElementById("yourId").focus()

document.querySelector('input').addEventListener('focus', e => {
const { value } = e.target;
e.target.setSelectionRange(value.length, value.length);
});
<input value="my text" />

const end = input.value.length


input.setSelectionRange(end, end)
// 👇 scroll to the bottom if a textarea has long text
input.focus()

我从这里得到了最好的答案,并创建了一个在Chrome中工作良好的功能。

  1. 您需要将逻辑封装在一个超时中,因为您必须等待焦点完成后才能访问所选内容
  2. 要将光标放在末尾,选择起始点需要放在末尾
  3. 为了滚动到输入字段的末尾,scrollLeft需要匹配scrollWidth

/**
* Upon focus, set the cursor to the end of the text input
* @param {HTMLInputElement} inputEl - An HTML <input> element
*/
const setFocusEnd = (inputEl) => {
setTimeout(() => {
const { scrollWidth, value: { length } } = inputEl;
inputEl.setSelectionRange(length, length);
inputEl.scrollLeft = scrollWidth;
}, 0);
};


document
.querySelector('input')
.addEventListener('focus', (e) => setFocusEnd(e.target));
html, body {
width: 100%;
height: 100%;
margin: 0;
}


body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}


input:focus {
background-color: hsla(240, 100%, 95%, 1.0);
}
<input
type="text"
placeholder="Search..."
value="This is some really, really long text">