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


308

将焦点设置到元素之后,通过JavaScript将光标放置在输入文本元素中文本末尾的最佳方法(我想是最简单的方法)是什么?

Answers:


170

我在IE中遇到了同样的问题(通过RJS /原型设置焦点之后)。当该字段已有值时,Firefox已经将光标留在末尾。IE迫使光标移至文本的开头。

我得出的解决方案如下:

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

IE7和FF3均适用


3
文本区域将是什么?
Tareq 2010年

19
现在可在Chrome浏览器中运行(9.0.597.98)
Matt

6
现在在IE9中不起作用 -光标跳到该字段的开头。

6
同样在FF 8中也不起作用。chenosaurus的解决方案似乎可行。
simon

3
在Chrome 24.0.1312.57,IE 9.0.8112中为我工作,但在Firefox 18.0.2中却没有。–
克里斯-Haddox Technologies

190

有一种简单的方法可以使它在大多数浏览器中运行。

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

但是,由于一些浏览器的怪癖,一个更具包容性的答案看起来像这样

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

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

使用Vanilla JS addEvent从此答案借用函数)


怪癖

Chrome有一个奇怪的怪癖,即在光标移到该字段之前触发焦点事件。这使我的简单解决方案搞砸了。解决此问题的两种方法:

  1. 您可以添加0毫秒的超时(以将操作推迟到清除堆栈为止
  2. 您可以将事件从更改focusmouseup。除非您仍然关注焦点,否则这对于用户而言将是非常烦人的。我对这些选项都不是很喜欢。

此外,@ vladkras指出,某些较旧版本的Opera在有空格时会错误地计算长度。为此,您可以使用巨大的数字,该数字应大于字符串。


2
在Chrome 24.0.1312.57,IE 9.0.8112和Firefox 18.0.2中为我工作
克里斯-Haddox Technologies

4
这是一个很好的解决方案,而不是观察(麻烦),代码少,比这里讨论的替代方法更易于理解。谢谢。
Derek Litz 2013年

我宁愿只在第一个焦点事件上这样做,并立即调用它。否则,每次单击该字段时,光标将移至末尾。
Damien

this.selectionStart = this.selectionEnd = 0; 这应该将焦点移到输入框的第一个字母之前。但是,相反,当我调试时,它甚至没有更改selectionEnd和selectionStart的值!而且也不要将其移动到第一个字符!
苏厄姆

1
据报道,Opera有时会错误地工作,selectionStartlength在空格上返回较小的数字。这就是为什么我使用10000或使用其他足够大的数字代替this.value.length(在IE8和IE11上测试)的原因
vladkras 2015年

160

试试这个,它对我有用:

//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中不会更改。


2
就像onfocus =“ this.value = this.value;
Tareq 2010年

15
在设置值之前先设置焦点是使其在Chrome中起作用的关键。
anatoly techtonik 2011年

7
为什么将this.第2、3和4行放在输入前面?我们已经知道这input是输入元素。使用this似乎多余。否则,很好的解决方案!
The111 2012年

3
@Tareq他们不一样。这个技巧比公认的答案要好得多。
刘易斯

4
更容易:$input.focus().val($input.val());
milkovsky '17

99

经过一番研究之后,我发现最好的方法是setSelectionRange在浏览器支持的情况下使用该功能。如果不是,请恢复使用Mike Berrow答案中的方法(即用自身替换值)。

scrollTop如果我们处于垂直滚动状态,我还设置了较高的值textarea。(使用任意高值似乎比$(this).height() Firefox和Chrome。)

我已经将它作为jQuery插件使用。(如果您不使用jQuery,我相信您仍然可以很容易地获得要点。)

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

它可以作为PutCursorAtEnd插件jquery.com上使用。为了您的方便,版本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);

4
为什么要计算长度?如果仍然要超调,为什么不只是this.setSelectionRange(9999,9999)?
PRMan

21
<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中对我有用


很好的第一个现成的解决方案,似乎对FF6和IE8都适用。
simon

3
由于某种原因,流行的答案对我不起作用。这工作完美。
metric152

在IE9中不适用于我。错误:SCRIPT16389: Unspecified error.
苏咸

1
完全在FF 46,铬51,和IE 11
webdevguy

这在IE 8中有效,而其他一些选项则无效。谢谢。
BenMaddox

17

我在chrome上取得了很大的成功,尝试了以下方法

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

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

快速淘汰:

它采用类集中于其的每个输入字段,然后将输入字段的旧值存储在变量中,然后将空字符串应用于输入字段。

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


完善!所有其他解决方案都不适合我,只有您的解决方案适合我。也许是因为我使用php将值分配给textarea,而js无法检测到该值,所以js必须等待1毫秒。
zac1987

3
@ zac1987可能不是这样,因为php会渲染html,html会加载到客户端,然后js会运行。您可能没有在等待文档就绪事件。
reconbot 2012年

只是要指出,像这样使用setTimeout可能会导致不可预测的结果。在某些情况下,代码可能会正确运行,例如有时在1ms内可能会更改输入,而不会重置val。同样重要的是要注意,最小等待时间为1毫秒。因此,如果您有一些cpu绑定方法,则焦点可能要等待1毫秒以上。这将使UI无响应。而且,由于.val()方法仍然会触发UI更改,因此这不是必需的。
卢瓦克福雷-拉克鲁瓦

10

这是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>


1
谢谢@MaxAlexanderHanna,我只参加el.focus()了会议,else if所以在某些情况下不起作用。我现在在chrome和(颤抖) IE中验证了此作品
Andy Raddatz

截至2019年12月7日已在IE和CHROME中进行了测试和工作。谢谢,支持。
马克斯·亚历山大·汉纳

太棒了,它可以在Catalina Beta的Safari中使用。
NetOperator Wibby


7

仍然需要中间变量(请参见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>

6

el.setSelectionRange(-1, -1);

https://codesandbox.io/s/peaceful-bash-x2mti

此方法在一个调用中更新HTMLInputElement.selectionStart,selectionEnd和selectionDirection属性。

https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLInputElement/setSelectionRange

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


这对我来说非常完美,而且最简单。+1
克里斯·法尔

我还必须包含onfocus =“ this.value = this.value;”。来自Mike Berrow的答案
克里斯·法尔

5

对于所有情况下的所有浏览器:

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事件处理程序中移动光标,则需要超时


请注意,这会在Android上引起问题,因为范围选择会将数据放入键盘缓冲区,这意味着您键入的任何键最终都会复制输入中的文本,这并不是最有用的。
Mike'Pomax'Kamermans

1
这真是太神奇了,在ie中对我来说很棒!我有一堆需要scrollLeft的输入,并且确实做了一些奇怪的事情,所以我一直在寻找可以用于垫片的东西,就是这样。它在其他浏览器中不起作用,但是对于没有任何作用的地方,这是惊人的!
zazvorniki

5

我非常喜欢这个被接受的答案,但是它在Chrome中停止工作了。在Chrome中,要使光标移至末尾,需要更改输入值。解决方法如下:

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

1
这是目前对我来说在Chrome上实际可用的解决方案。语法很奇怪,但是,嘿,现在将学习使用该解决方案!
山姆·贝勒罗斯

3

在jQuery中,

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

2
仅当$('input')获得焦点时,此函数才将value属性分配给value。它不会将光标发送到该行的末尾。
vrish88

3

这个问题很有趣。最令人困惑的是,我发现没有解决方案可以完全解决问题。

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

  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. 您需要在onfocus和onclick事件中将此人称为。

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

它适用于所有设备的浏览器!!!


2

我刚刚发现,在iOS中,setting textarea.textContent属性每次都会将光标置于textarea元素中文本的末尾。该行为是我的应用程序中的错误,但似乎是您可以有意使用的东西。


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

这个解决方案比现有的jQuery解决方案有什么优势?
罗凡尼

这是另一种解决方案。如果您没有许可编辑html文件和仅使用javascript,则此解决方案还不错;)我有同样的情况!
HanKrum

此解决方案对我有用,其他jQuery解决方案可能与您在集中输入值之前清空输入值的事实无关。
塔尔西伯尼


1

如果输入字段仅需要静态默认值,则通常使用jQuery:

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

这似乎适用于所有浏览器。


1

尽管这可能是一个有很多答案的老问题,但我遇到了一个类似的问题,但所有答案都并非我想要的和/或解释得不好。selectionStart和selectionEnd属性的问题在于输入类型号不存在它们(当询问文本类型时,我认为这可能会帮助其他可能需要关注其他输入类型的人)。因此,如果您不知道函数将要聚焦的输入类型是否是类型编号,则无法使用该解决方案。

跨浏览器并适用于所有输入类型的解决方案非常简单:

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

这样,光标位于输入元素的末尾。
因此,您要做的就是这样(使用jquery,前提是可以通过clicked元素的data-focus-element'data属性访问希望聚焦的元素选择器,并且函数在单击'.foo'之后执行元件):

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

为什么这样做?简单来说,当调用.focus()时,焦点将添加到输入元素的开头(这是此处的核心问题),而忽略了输入元素中已经有值的事实。但是,当更改输入的值时,光标会自动放置在输入元素内值的末尾。因此,如果使用先前在输入中输入的相同值覆盖该值,则该值看起来将保持不变,但是光标将移至末尾。


1

尝试使用适用于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()

0

单击文本区域时将光标设置到文本末尾。此代码的变化形式是……也可以使用!适用于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();
 }


0

我想将光标放在contenteditable = true的“ div”元素的末尾,并得到了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


0

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

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中使用。在移动设备上,我没有尝试过。


0

检查此解决方案!

//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>


0

超级简单(您可能必须专注于输入元素)

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

-1

我之前曾尝试过这些建议,但没有一个对我有用(在Chrome中对它们进行了测试),所以我编写了自己的代码-并且它在Firefox,IE,Safari,Chrome中都可以正常工作...

在Textarea中:

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

-1

这是我的答案的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;
}

-1

尝试以下代码:

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

1
OP表示希望添加尾随空白是否是副作用?
Charles Duffy 2015年

但是,为什么我的答案是-2?我不明白!这是有效的示例
msroot

现在,您已解决了未指定的副作用,这显然不是很明显的错误(从不良行为的意义上来说),但是我可以理解为什么在此之前它会被否决。在这一点上,我不赞成的原因可能是性能低下-读写无限制长度的值可能会变慢;setSelectionRange当/在支持的地方,该方法肯定会更加有效。
Charles Duffy

1
(嗯-那我不确定通过重新设置预先存在的值也可以为现有答案添加什么;如果确实添加了一些新的/重要的内容,则添加了一些描述其含义的文本,而不仅仅是代码, 有助于)。
Charles Duffy 2015年

当然-OP在问题中是否表明他们想要一个空间?如果不是,则不属于规范的一部分。因此,“未指定”。
Charles Duffy 2015年

-1

尽管我回答的太迟了,但是对于将来的查询,这将有所帮助。它也可以在contenteditablediv中使用。

从哪里开始需要集中精力;编写此代码-

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();
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.