【发布时间】:2010-10-05 09:29:17
【问题描述】:
在将焦点设置到元素后,通过 JavaScript 将光标置于输入文本元素中文本末尾的最佳方式(我认为是最简单的方式)是什么?
【问题讨论】:
标签: javascript
在将焦点设置到元素后,通过 JavaScript 将光标置于输入文本元素中文本末尾的最佳方式(我认为是最简单的方式)是什么?
【问题讨论】:
标签: javascript
有一种简单的方法可以让它在大多数浏览器中运行。
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 (从 this answer 借用 addEvent 函数)
// 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'>
Chrome 有一个奇怪的怪癖,焦点事件在光标移动到字段之前触发;这搞砸了我的简单解决方案。解决此问题的两个选项:
focus 更改为mouseup。除非您仍然跟踪焦点,否则这对用户来说会很烦人。我不是很喜欢这两种选择。另外,@vladkras 指出,一些旧版本的 Opera 在包含空格时会错误地计算长度。为此,您可以使用一个比您的字符串更大的数字。
【讨论】:
selectionStart 和 length 在空格上返回较小的数字。这就是为什么我使用 10000 或任何其他足够大的数字而不是 this.value.length(在 IE8 和 IE11 上测试)
contenteditable 元素(不是输入)
我在 IE 中遇到了同样的问题(在通过 RJS/原型设置焦点之后)。 当该字段已经有值时,Firefox 已经将光标留在了末尾。 IE 将光标强制到文本的开头。
我得出的解决方案如下:
<input id="search" type="text" value="mycurrtext" size="30"
onfocus="this.value = this.value;" name="search"/>
这适用于 IE7 和 FF3
【讨论】:
试试这个,它对我有用:
//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 中更改。
【讨论】:
this. 放在第 2、3 和 4 行的输入前面?我们已经知道input 是输入元素。使用this 似乎是多余的。否则很好的解决方案!
$input.focus().val($input.val());
经过一番修改后,我发现最好的方法是在浏览器支持的情况下使用setSelectionRange 函数;如果没有,请恢复使用 Mike Berrow 答案中的方法(即用自身替换值)。
我还将scrollTop 设置为较高的值,以防我们处于可垂直滚动的textarea 中。 (在 Firefox 和 Chrome 中使用任意高值似乎比 $(this).height() 更可靠。)
我把它做成了一个 jQuery 插件。 (如果您不使用 jQuery,我相信您仍然可以轻松掌握要点。)
我在 IE6、IE7、IE8、Firefox 3.5.5、Google Chrome 3.0、Safari 4.0.4、Opera 10.00 中进行了测试。
在 jquery.com 上以 PutCursorAtEnd plugin 的形式提供。为了您的方便,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);
【讨论】:
<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.x 和 Opera 11.x
【讨论】:
SCRIPT16389: Unspecified error.
现在是 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>
【讨论】:
else if 中只有el.focus(),所以在某些情况下它不起作用。我现在在 chrome 和 (shudder) IE 中验证了它的工作原理
我在 chrome 中尝试了以下方法并取得了巨大的成功
$("input.focus").focus(function () {
var val = this.value,
$this = $(this);
$this.val("");
setTimeout(function () {
$this.val(val);
}, 1);
});
简要介绍:
它获取每个类焦点所在的输入字段,然后将输入字段的旧值存储在一个变量中,然后将空字符串应用于输入字段。
然后它等待 1 毫秒并再次放入旧值。
【讨论】:
el.setSelectionRange(-1, -1);
https://codesandbox.io/s/peaceful-bash-x2mti
此方法更新 HTMLInputElement.selectionStart、selectionEnd、 和 selectionDirection 属性一次调用。
https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange
在其他 js 方法中,-1 通常表示(到)最后一个字符。这也是这种情况,但我在文档中找不到明确提及这种行为。
【讨论】:
简单。编辑或更改值时,先放置焦点再设置值。
$("#catg_name").focus();
$("#catg_name").val(catg_name);
【讨论】:
仍然需要中间变量,(见 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>
【讨论】:
适用于所有情况下的所有浏览器:
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 事件处理程序中移动光标,则需要超时
【讨论】:
我非常喜欢接受的答案,但它在 Chrome 中停止工作。在 Chrome 中,要使光标走到末尾,输入值需要更改。解决方法如下:
<input id="search" type="text" value="mycurrtext" size="30"
onfocus="var value = this.value; this.value = null; this.value = value;" name="search"/>
【讨论】:
试试这个与 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()
【讨论】:
const end = input.value.length
input.setSelectionRange(end, end)
// ? scroll to the bottom if a textarea has long text
input.focus()
【讨论】:
在 jQuery 中是
$(document).ready(function () {
$('input').focus(function () {
$(this).attr('value',$(this).attr('value'));
}
}
【讨论】:
这个问题很有趣。最令人困惑的是,我没有找到完全解决问题的解决方案。
+++++++解决方案+++++++
你需要一个 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);
}
}
你需要在 onfocus 和 onclick 事件中调用这个人。
<input type="text" value="Test Field" onfocus="moveCursorToEnd(this)" onclick="moveCursorToEnd(this)">
它适用于所有设备和浏览器!!!!
【讨论】:
我刚刚发现在iOS中,设置textarea.textContent属性每次都会将光标放在textarea元素中的文本末尾。该行为是我的应用程序中的一个错误,但似乎是您可以有意使用的东西。
【讨论】:
var valsrch = $('#search').val();
$('#search').val('').focus().val(valsrch);
【讨论】:
采取一些答案.. 制作单行 jquery。
$('#search').focus().val($('#search').val());
【讨论】:
如果输入字段只需要一个静态默认值,我通常会使用 jQuery:
$('#input').focus().val('Default value');
这似乎适用于所有浏览器。
【讨论】:
虽然这可能是一个有很多答案的老问题,但我遇到了一个类似的问题,没有一个答案是我想要的和/或没有得到很好的解释。 selectionStart 和 selectionEnd 属性的问题在于它们对于输入类型编号不存在(虽然问题是针对文本类型提出的,但我认为它可能会帮助其他可能需要关注其他输入类型的人)。因此,如果您不知道函数将关注的输入类型是否为类型编号,则无法使用该解决方案。
适用于跨浏览器并适用于所有输入类型的解决方案相当简单:
这样光标就在输入元素的末尾。
因此,您要做的就是这样(使用jquery,只要可以通过单击元素的“data-focus-element”数据属性访问希望聚焦的元素选择器,并且该函数在单击“.foo”后执行)元素):
$('.foo').click(function() {
element_selector = $(this).attr('data-focus-element');
$focus = $(element_selector);
value = $focus.val();
$focus.focus();
$focus.val(value);
});
为什么会这样?简单来说,当调用 .focus() 时,焦点将被添加到输入元素的开头(这是这里的核心问题),忽略了输入元素已经有值的事实。但是,当输入的值发生更改时,光标会自动放置在输入元素内的值的末尾。因此,如果您使用之前在输入中输入的相同值覆盖该值,则该值看起来不会被触及,但是光标会移动到末尾。
【讨论】:
document.querySelector('input').addEventListener('focus', e => {
const { value } = e.target;
e.target.setSelectionRange(value.length, value.length);
});
<input value="my text" />
【讨论】:
点击文本区域时将光标设置到文本末尾... 此代码的变体是......也有效!适用于 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();
}
【讨论】:
如果先设置值再设置焦点,光标会一直出现在最后。
$("#search-button").click(function (event) {
event.preventDefault();
$('#textbox').val('this');
$("#textbox").focus();
return false;
});
这是要测试的小提琴 https://jsfiddle.net/5on50caf/1/
【讨论】:
我想将光标放在 contenteditable = true 的“div”元素的末尾,我得到了Xeoncross code 的解决方案:
<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
【讨论】:
我也遇到了同样的问题。最后这对我有用:
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>
【讨论】:
超级简单(您可能需要专注于输入元素)
inputEl = getElementById('inputId');
var temp = inputEl.value;
inputEl.value = '';
inputEl.value = temp;
【讨论】:
我之前尝试过这些建议,但没有一个对我有用(在 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);}
【讨论】:
这是我的答案jsFiddle demo。该演示使用 CoffeeScript,但如果需要,您可以convert it to plain 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;
}
【讨论】: