首页 文章

编辑电话号码时,光标跳到最后

提问于
浏览
1

Code: https://codepen.io/anon/pen/MmjgNR
Problem: 使用蒙版编辑电话号码时,光标跳到最后 .
Example: (123) 456-7890 . 当我尝试删除数字5并使其为7时,光标立即移动到结尾: (123) 46-7890 .

如果您有任何疑问,请告诉我 .
如果你投票,请提及原因,以便我能够纠正 .

1 回答

  • 1

    前言

    I know literally nothing about AngularJS. 我之前从未使用过它 . 这是我第一次看到它 . 我不知道它做了什么 . 它似乎所做的就是添加一个庞大的抽象层来混淆代码,并证明增加了对可以看透这种混淆的“内部人”的IT支出 . 没有AngularJS,你的任务会更简单 . 但是,正如我所说,我不知道AngularJS是什么,也不知道它是做什么的,所以我可能错了 .

    基本解决方案

    报告行为的原因是每次用户键入任何内容时,您的脚本都会覆盖 <input> 值 . 通常和基本的解决方案是在覆盖行为之前 store the caret positionelement.val(...) ):

    var caretPosition = element[0].selectionStart;
    

    ......和 restore it immediately after:

    element[0].focus(); element[0].setSelectionRange(caretPosition, caretPosition);
    

    你的脚本确实包含一个插入处理代码的存根,但它确实没有任何东西,它只是通过故意将插入符号移动到字符串的末尾来重复它自己的意外行为 . 这种毫无意义的行为似乎暗示了任何重用代码来编写自己的插入处理代码的人 . 用我的代码替换该存根 .

    实例

    var app = angular.module('plunker', []);
    
    app.controller('MainCtrl', function($scope) {$scope.name = 'Phone Number';});
    
    app.directive('abcXyz', function($filter) {
       var mobileFilter, mobileReverse;
       mobileFilter = $filter('mobileFilter');
       mobileReverse = $filter('mobileReverse');
       return {
           restrict: 'A',
           require: 'ngModel',
           link: function(scope, element, attrs, modelCtrl) {
               var formatter, parser;
               parser = function(value) {
                   var formatted;
                   formatted = mobileReverse(value);
    /* solution */ var caretPosition = element[0].selectionStart;
    /* solution */ if (caretPosition === 4) caretPosition += 3;
    /* solution */ if (caretPosition === 10) ++caretPosition;
                   element.val(mobileFilter(formatted));
    /* solution */ element[0].selectionStart = element[0].selectionEnd = caretPosition;
                   return formatted;
               };
               modelCtrl.$formatters.push(formatter);
               return modelCtrl.$parsers.unshift(parser);
           }
       };
    });
    
    app.filter('mobileFilter', function() {
        return function(value) {
            var len, val;
            if (!value) return;
            val = value.toString().replace(/\D/g, "");
            len = val.length;
            if (len < 4) return val;
            else if (3 < len && len < 7) 
                return "(" + (val.substr(0, 3)) + ") " + (val.substr(3));
            else if (len > 6) 
                return "(" + (val.substr(0, 3)) + ") " + (val.substr(3, 3)) + 
                "-" + (val.substr(6, 4));
            return value;
        }
    });
    
    app.filter("mobileReverse", () => value => !!value && value.replace(/\D/g, "")
        .substr(0, 10));
    
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js">
    </script>
    <html ng-app="plunker">
     <body ng-controller="MainCtrl">
       <p>{{name}}!</p>
       <input type="tel" abc-xyz ng-model="formData.Phone" name="worktype" 
       maxlength="14" required="required" ng-pattern="(/[0-9-()]*[1-9][0-9-()]*/);" 
       autoComplete="off">
     </body>
    </html>
    

    一个完整的解决方案

    基本的解决方案是改进,但它仍然不完美 . 它失败了退格 . 用户有时可以添加字母或删除强制破折号或括号 . 似乎你需要 a complex caret handler ,它具有退格,过滤器的意识,而不是一个,而是两个最后的插入位置 . 我已经在基本示例中包含了简单的过滤器感知:

    if (caretPosition === 4) caretPosition += 3;
    if (caretPosition === 10) ++caretPosition;
    

    但这还不够 . 此时,我无法向您发送 a complete caret handler ,但至少让我告诉您如何在AngularJS代码中包含退格感知:

    • 将属性 ng-keydown="registerBackspace($event)" 添加到HTML标记 <input type="tel"> .

    • 用此调用替换您的 app.controller() 电话:

    app.controller('MainCtrl', function($scope) {   $scope.name = 'Phone Number';   $scope.registerBackspace = event => window.phoneBackspace = event.keyCode === 8; });
    
    • 现在您有一个全局变量 window.phoneBackspace ,它指示在电话输入字段中按下的最后一个键是否为退格键( truefalse ) .

    我不喜欢全局变量,但我对AngularJS一无所知,想知道如何使用自己的函数传递这些信息(也不知道它是否允许这样做) .

    最后的话

    如果您认为主持人是白痴,请立即投票 .

    文学

相关问题