【问题标题】:Set Caret position in Input with AngularJS使用 AngularJS 在输入中设置插入符号位置
【发布时间】:2014-04-29 17:41:52
【问题描述】:

我需要更改输入的插入符号位置,其中添加了给定数量的数字 (Example)。

app.controller('MainCtrl', function($scope, $element, $timeout, $filter) {
  //$scope.val = '12';
  $scope.$watch('val', function(newValue, oldValue) {
    if (!isNaN(newValue)) {
      if (newValue.length > 3) {
        //Set Caret Position  
      }
    }
  });
});

有没有可能做这样的事情example

我需要例如:

输入:1234。

所以插入符号的位置将是 2。

新数字:9

最终:12934

提前致谢。

【问题讨论】:

    标签: javascript angularjs angularjs-scope


    【解决方案1】:

    我相信您可以通过在输入中使用.setSelectionRange() 来做到这一点。我更新了您的示例 - 看看这是否是您想要的:http://plnkr.co/edit/bIJAPPAzkzqLIDUxVlIy?p=preview

    注意:IE8 不支持setSelectionRange(参见https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement.setSelectionRange),因此如果您需要支持 IE

    【讨论】:

      【解决方案2】:

      我认为这样的东西在指令中看起来更好。例如:

      app.directive('caret', function() {
      
          function setCaretPosition(elem, caretPos) {
              if (elem !== null) {
                  if (elem.createTextRange) {
                      var range = elem.createTextRange();
                      range.move('character', caretPos);
                      range.select();
                  } else {
                      if (elem.setSelectionRange) {
                          elem.focus();
                          elem.setSelectionRange(caretPos, caretPos);
                      } else
                          elem.focus();
                  }
              }
          }
      
          return {
              scope: {value: '=ngModel'},
              link: function(scope, element, attrs) {
                  var caret = Number(attrs.caret);
                  scope.$watch('value', function(newValue, oldValue) {
                      if (newValue && newValue != oldValue && !isNaN(newValue) && newValue.length > (caret + 1)) {
                          setCaretPosition(element[0], caret);
                      }
                  });
              }
          };
      });
      

      用法:

      <input ng-model='val' caret="2" />
      

      我使用setCaretPosition 函数从this 答案中进行跨浏览器光标定位。

      演示:http://plnkr.co/edit/5RSgzvyd8YOTaXPsYr8A?p=preview

      【讨论】:

      【解决方案3】:

      我认为最好的方法是在处理 DOM 操作时创建一个可重用的指令。

      演示链接:http://plnkr.co/edit/qlGi64VO1AOrNpxoKA68?p=preview

      var app = angular.module('angularjs-starter', []);
      
      app.controller('MainCtrl', function($scope, $element, $timeout, $filter) {
        $scope.$watch('val', function(newValue, oldValue) {
          if (!isNaN(newValue)) {
            if (newValue.length > 3) {
            // $element.find('input')[0].selectionEnd  = 2;
            }
          }
        });
      });
      
      app.directive('setCaret', function() {
      
        return {
          restrict: 'A',
          link: function(scope,element,attrs) {
            var changed = false;
            element.bind('keypress', function() {
              if(element[0].selectionStart > 3 && !changed) {
                changed = true;
                element[0].selectionEnd = parseInt(attrs.position, 10);
              }
            })
      
          },
        }
      
      })
      

      您可以在控制器的注释掉部分看到我们可以通过使用 $element 来访问它,但是由于这是 DOM 并且控制器不是用于 DOM 操作的,我们需要将它变成一个指令。

      【讨论】:

        【解决方案4】:

        我也遇到了同样的问题。

        我想通过创建一个适当的指令来解决它。你可以找到它here。尽情享受吧!

        用法

        include指令,通过caret-aware属性声明

        <script src="https://cdn.rawgit.com/leodido/ng-caret-aware/master/caretaware.min.js"></script>
        <script type="text/javascript">
          var app = angular.module('myModule', ['leodido.caretAware']);
        </script>
        ...
        <div data-ng-app="app">
            <input type="text" name="myname" caret-aware="cursor"/>
        </div>
        

        然后在作用域上,您将拥有一个变量 cursor,其中包含名为 myname 的输入中插入符号的位置。

        不过,该指令的控制器公开了一个 API

        • getPosition
        • setPosition

        其他使用示例参见上述链接的 github 存储库的example 目录。

        【讨论】:

          【解决方案5】:

          jsfiddled 一个可行的解决方案。 所以基本上,你必须创建一个指令:

          app.directive('keypressdetector', function($compile){
              return {
              restrict:'AEC',
              link: function(scope, element, attrs){
                  element.bind("keypress", function (event) {
                      if(event.which === 13) {
                                      var selectionStart = element[0].selectionStart;
                        var value = element.val();
                        var valueLength = value.length;
                        var newValue= '';
                        if (selectionStart == valueLength){
                          newValue = value;
                        } else {
                          newValue = value.substring(selectionStart, valueLength);
                        }
                        var newElement = angular.element('<input type="text" value="' + newValue +'"/>')
                        angular.element(document.body).append(newElement);
                      }
                  });
              }
            };
          });
          

          在这种情况下,您的控制器将毫无用处。 您可以像这样调用指令(参见:keypressdetector):

          <div ng-app="myapp">
          <div ng-controller="LoginController">
              <div>Hello {{ user.firstName }}</div>
              <input ng-model="user.firstName" keypressdetector />
              <input type="submit" ng-click="login()" value="Login"/>
              <div ng-repeat="login in logins">{{ login }}</div>
          </div>
          </div>
          

          See demo : https://jsfiddle.net/Lt7aP/3468/

          【讨论】:

            猜你喜欢
            • 2011-08-22
            • 2011-06-05
            • 2010-10-06
            • 1970-01-01
            • 2013-07-25
            • 2013-07-18
            • 1970-01-01
            • 2020-08-17
            • 1970-01-01
            相关资源
            最近更新 更多