【问题标题】:When editing phone number, cursor jumps to the end编辑电话号码时,光标跳到末尾
【发布时间】:2017-04-25 02:25:58
【问题描述】:

代码:https://codepen.io/anon/pen/MmjgNR
问题:使用蒙版编辑电话号码时,光标跳到末尾。
示例: (123) 456-7890。当我尝试删除数字 5 并将其变为 7 时,光标立即移动到末尾:(123) 46-7890

如果您有任何问题,请告诉我。
如果您投反对票,请说明原因,以便我更正。

【问题讨论】:

  • 避免被否决的最佳方法是提出一个好问题。请阅读:stackoverflow.com/help/how-to-ask
  • 尝试使用 jquery 来验证和格式化 onblur 事件上的数字,而不是角度验证。这样可以防止最后跳跃。
  • @T.Shah 有什么办法可以通过现有的角度验证来修复它,因为我对 SSN、PHONE、DL 等有不同的指令,感谢您的回复。

标签: javascript html angularjs


【解决方案1】:

前言

我对 AngularJS 一无所知。我以前从未使用过它。这是我第一次看到它。我不知道它有什么作用。它似乎所做的只是添加一个巨大的抽象层来混淆代码,并证明增加 IT 支出给能够看穿这种混淆的“内部人员”是合理的。如果没有 AngularJS,你的任务会简单得多。但是,正如我所说,我不知道 AngularJS 是什么,也不知道它的作用,所以我可能是错的。

基本解决方案

报告行为的原因是每次用户键入任何内容时,您的脚本都会覆盖 <input> 值。通常和基本的解决方案是在覆盖之前存储插入符号位置 (element.val(...)):

var caretPosition = element[0].selectionStart;

...并在之后立即恢复:

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>

完整的解决方案

基本解决方案是一种改进,但它仍然不完美。退格失败。用户有时可以添加字母或删除强制性破折号或括号。您似乎需要一个复杂的插入符号处理程序,它能够识别退格、过滤器,而不是一个,而是 两个 最后插入符号位置。我已经在基本示例中包含了简单的过滤器意识:

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

但这还不够。在这一点上,我无法向您提供完整的插入符号处理程序,但至少让我向您展示如何在 AngularJS 代码中包含退格意识:

  1. 将属性ng-keydown="registerBackspace($event)"添加到HTML标签&lt;input type="tel"&gt;
  2. 用这个电话代替你的app.controller()电话:
app.controller('MainCtrl', function($scope) {
$scope.name = '电话号码';
$scope.registerBackspace = event => window.phoneBackspace = event.keyCode == = 8;
});
  1. 现在您有一个全局变量window.phoneBackspace,它指示在电话输入字段中按下的最后一个键是否为退格键(truefalse)。

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

最后的话

如果您认为版主是白痴,请投票。

文学

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-21
    • 2014-10-09
    • 1970-01-01
    • 2020-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多