【问题标题】:Set keyboard caret position in html textbox在 html 文本框中设置键盘插入符号位置
【发布时间】:2010-10-05 11:31:41
【问题描述】:

有人知道如何将文本框中的键盘插入符号移动到特定位置吗?

例如,如果一个文本框(例如输入元素,而不是文本区域)中有 50 个字符,我想将插入符号放在第 20 个字符之前,我该怎么做?

这与这个问题不同:jQuery Set Cursor Position in Text Area,它需要 jQuery。

【问题讨论】:

    标签: javascript textbox input


    【解决方案1】:

    HTMLInputElement.setSelectionRange(selectionStart, selectionEnd);

    // References
    var e = document.getElementById( "helloworldinput" );
    
    // Move caret to beginning on focus
    e.addEventListener( "focus", function( event )
    {
        // References
        var e = event.target;
    
        // Action
        e.setSelectionRange( 0, 0 );            // Doesn’t work for focus event
        
        window.setTimeout( function()
        {
            e.setSelectionRange( 0, 0 );        // Works
            //e.setSelectionRange( 1, 1 );      // Move caret to second position
            //e.setSelectionRange( 1, 2 );      // Select second character
    
        }, 0 );
    
    }, false );
    

    浏览器兼容性(仅适用于类型:文本、搜索、网址、电话和密码): https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange#Specifications

    【讨论】:

      【解决方案2】:

      我找到了解决此问题的简单方法,已在 IE 和 Chrome 中进行了测试:

      function setCaret(elemId, caret)
       {
         var elem = document.getElementById(elemId);
         elem.setSelectionRange(caret, caret);
       }
      

      将文本框 ID 和插入符号位置传递给此函数。

      【讨论】:

      • 短而优雅
      【解决方案3】:

      我会修复如下条件:

      function setCaretPosition(elemId, caretPos)
      {
       var elem = document.getElementById(elemId);
       if (elem)
       {
        if (typeof elem.createTextRange != 'undefined')
        {
         var range = elem.createTextRange();
         range.move('character', caretPos);
         range.select();
        }
        else
        {
         if (typeof elem.selectionStart != 'undefined')
          elem.selectionStart = caretPos;
         elem.focus();
        }
       }
      }
      

      【讨论】:

        【解决方案4】:

        摘自乔什·斯托多拉的Setting keyboard caret Position in a Textbox or TextArea with Javascript

        一个通用函数,允许您在文本框或文本区域的任意位置插入插入符号:

        function setCaretPosition(elemId, caretPos) {
            var elem = document.getElementById(elemId);
        
            if(elem != null) {
                if(elem.createTextRange) {
                    var range = elem.createTextRange();
                    range.move('character', caretPos);
                    range.select();
                }
                else {
                    if(elem.selectionStart) {
                        elem.focus();
                        elem.setSelectionRange(caretPos, caretPos);
                    }
                    else
                        elem.focus();
                }
            }
        }
        

        第一个预期参数是您希望在其上插入键盘插入符号的元素的 ID。如果无法找到该元素,则不会发生任何事情(显然)。第二个参数是插入符号位置索引。零会将键盘插入符号放在开头。如果您传递的数字大于元素值中的字符数,它将把键盘插入符号放在末尾。

        在 IE6 及更高版本、Firefox 2、Opera 8、Netscape 9、SeaMonkey 和 Safari 上测试。不幸的是,在 Safari 上它不能与 onfocus 事件结合使用)。

        使用上述函数强制键盘插入符在获得焦点时跳转到页面上所有文本区域的末尾的示例:

        function addLoadEvent(func) {
            if(typeof window.onload != 'function') {
                window.onload = func;
            }
            else {
                if(func) {
                    var oldLoad = window.onload;
        
                    window.onload = function() {
                        if(oldLoad)
                                oldLoad();
        
                        func();
                    }
                }
            }
        }
        
        // The setCaretPosition function belongs right here!
        
        function setTextAreasOnFocus() {
        /***
         * This function will force the keyboard caret to be positioned
         * at the end of all textareas when they receive focus.
         */
            var textAreas = document.getElementsByTagName('textarea');
        
            for(var i = 0; i < textAreas.length; i++) {
                textAreas[i].onfocus = function() {
                    setCaretPosition(this.id, this.value.length);
                }
            }
        
            textAreas = null;
        }
        
        addLoadEvent(setTextAreasOnFocus);
        

        【讨论】:

        • if(elem.selectionStart) 在 selectionStart 为 0 时中断,正如 jhnns 的回答所指出的那样。
        • 这对我不起作用。当我单击实际的文本框时,我希望插入符号位置位于开头。看看我的小提琴jsfiddle.net/khx2w
        • setCaretPosition 函数工作得很好。但是,您的 addActionHandler 函数没有。但即使没有这个,我也无法让光标移到焦点上。很可能是因为浏览器会根据点击的位置自行设置光标位置。据我所知,似乎没有办法绕过它,但我可能完全错了。
        • 适用于 IE9、FF25,但不适用于 Chrome 30。总比没有好!
        • 博客链接失效了。
        【解决方案5】:

        答案中的链接已损坏,这个应该可以工作(所有学分都转到blog.vishalon.net):

        http://snipplr.com/view/5144/getset-cursor-in-html-textarea/

        如果代码再次丢失,这里有两个主要功能:

        function doGetCaretPosition(ctrl)
        {
         var CaretPos = 0;
        
         if (ctrl.selectionStart || ctrl.selectionStart == 0)
         {// Standard.
          CaretPos = ctrl.selectionStart;
         }
         else if (document.selection)
         {// Legacy IE
          ctrl.focus ();
          var Sel = document.selection.createRange ();
          Sel.moveStart ('character', -ctrl.value.length);
          CaretPos = Sel.text.length;
         }
        
         return (CaretPos);
        }
        
        
        function setCaretPosition(ctrl,pos)
        {
         if (ctrl.setSelectionRange)
         {
          ctrl.focus();
          ctrl.setSelectionRange(pos,pos);
         }
         else if (ctrl.createTextRange)
         {
          var range = ctrl.createTextRange();
          range.collapse(true);
          range.moveEnd('character', pos);
          range.moveStart('character', pos);
          range.select();
         }
        }
        

        【讨论】:

        • +1 用于基本功能,但必须进行一些调整。使用 range 方法时,必须从“pos”中减去行数。
        【解决方案6】:

        如果您需要关注某个文本框并且您唯一的问题是整个文本被突出显示而您希望插入符号位于末尾,那么在这种特定情况下,您可以使用将文本框值设置为自身的技巧聚焦后:

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

        【讨论】:

          【解决方案7】:
          function SetCaretEnd(tID) {
              tID += "";
              if (!tID.startsWith("#")) { tID = "#" + tID; }
              $(tID).focus();
              var t = $(tID).val();
              if (t.length == 0) { return; }
              $(tID).val("");
              $(tID).val(t);
              $(tID).scrollTop($(tID)[0].scrollHeight); }
          

          【讨论】:

          • Uncaught TypeError: Object [object HTMLInputElement] has no method 'startsWith'
          • @bobpaul: tID 应该是元素的 id,而不是元素对象本身。如果要传递元素对象,则只需删除此方法中的前 2 行即可。
          【解决方案8】:
          <!DOCTYPE html>
          <html>
          <head>
          <title>set caret position</title>
          <script type="application/javascript">
          //<![CDATA[
          window.onload = function ()
          {
           setCaret(document.getElementById('input1'), 13, 13)
          }
          
          function setCaret(el, st, end)
          {
           if (el.setSelectionRange)
           {
            el.focus();
            el.setSelectionRange(st, end);
           }
           else
           {
            if (el.createTextRange)
            {
             range = el.createTextRange();
             range.collapse(true);
             range.moveEnd('character', end);
             range.moveStart('character', st);
             range.select();
            }
           }
          }
          //]]>
          </script>
          </head>
          <body>
          
          <textarea id="input1" name="input1" rows="10" cols="30">Happy kittens dancing</textarea>
          
          <p>&nbsp;</p>
          
          </body>
          </html>
          

          【讨论】:

          • 这没有任何作用
          【解决方案9】:

          因为我确实需要这个解决方案,而典型的基线解决方案(关注输入 - 然后将值设置为等于自身不能跨浏览器工作 ,我花了一些时间调整和编辑所有内容以使其正常工作。在 @kd7 的代码的基础上,这是我想出的。

          尽情享受吧!适用于 IE6+、Firefox、Chrome、Safari、Opera

          Cross-browser caret positioning technique (example: moving the cursor to the END)

          // ** USEAGE ** (returns a boolean true/false if it worked or not)
          // Parameters ( Id_of_element, caretPosition_you_want)
          
          setCaretPosition('IDHERE', 10); // example
          

          肉和土豆基本上是@kd7的setCaretPosition,最大的调整是if (el.selectionStart || el.selectionStart === 0),在firefox中selectionStart从0开始,在boolean当然是转向 False,所以它在那里打破了。

          在 chrome 中,最大的问题是仅仅给它.focus() 是不够的(它一直选择所有文本!)因此,我们在调用我们的函数之前将自身的值设置为自身 el.value = el.value;,并且现在它具有使用 selectionStart 的输入的掌握和位置。

          function setCaretPosition(elemId, caretPos) {
              var el = document.getElementById(elemId);
          
              el.value = el.value;
              // ^ this is used to not only get "focus", but
              // to make sure we don't have it everything -selected-
              // (it causes an issue in chrome, and having it doesn't hurt any other browser)
          
              if (el !== null) {
          
                  if (el.createTextRange) {
                      var range = el.createTextRange();
                      range.move('character', caretPos);
                      range.select();
                      return true;
                  }
          
                  else {
                      // (el.selectionStart === 0 added for Firefox bug)
                      if (el.selectionStart || el.selectionStart === 0) {
                          el.focus();
                          el.setSelectionRange(caretPos, caretPos);
                          return true;
                      }
          
                      else  { // fail city, fortunately this never happens (as far as I've tested) :)
                          el.focus();
                          return false;
                      }
                  }
              }
          }
          

          【讨论】:

          • @mcpDESIGNS 当焦点放在文本输入上时,我正在尝试使用此功能,但我无处可去,请您帮忙使用纯 JavaScript 应用此功能吗?
          • @elad.chen 你是否想在他们关注文本框后立即将它们定位到文本框的末尾?
          • @mcpDESIGNS 我想在元素被聚焦后立即将光标放在字段的开头。见小提琴:jsfiddle.net/KuLTU/3
          • @elad.chen 抱歉,回复晚了!只需在 search_field_focus 函数中将该事件更改为 .onclick 而不是 .onfocus
          • el.value = el.value; [...] if(el !== null) - 我会交换这两行。如果el 为空,el.value = el.value 将失败,因此该行应位于if 内。
          【解决方案10】:

          我稍微调整了 kd7 的答案,因为当 selectionStart 偶然为 0 时,elem.selectionStart 将评估为 false。

          function setCaretPosition(elem, caretPos) {
              var range;
          
              if (elem.createTextRange) {
                  range = elem.createTextRange();
                  range.move('character', caretPos);
                  range.select();
              } else {
                  elem.focus();
                  if (elem.selectionStart !== undefined) {
                      elem.setSelectionRange(caretPos, caretPos);
                  }
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2011-01-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-22
            • 2022-01-14
            • 2013-05-21
            • 2010-10-06
            相关资源
            最近更新 更多