【问题标题】:Jquery keydown() with number format not work correctly on android webview带有数字格式的 Jquery keydown() 在 android webview 上无法正常工作
【发布时间】:2012-09-22 05:33:49
【问题描述】:

我在 android 浏览器/webview 上遇到了一个奇怪的行为。我正在测试一个将自动格式化为电话号码格式“(xxx)xxx-xxxx”的输入。但是后来发生的事情是,当我在 androids 键盘上点击或按任意数字时,第一个输入是这样的“(x”但随后光标在“(”和“x”之间。有没有办法把光标放在后面“x”值?

我在 iPhone 和 windows 网络浏览器上对此进行了测试,它运行良好。如果我的 jquery 或 javascripts 有错误,请告诉我。

谢谢

HTML 代码:

<html>
    <head> 
        <title>Sample Phone Number Format</title>
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
    </head>
    <body>
        <input type="text" id="phone" /> 

        <script type="text/javascript">
            $('#phone').on('keydown', function (event) {

                objval = $(this).val();
                if (event.keyCode == 46 || event.keyCode == 8) {} else {
                    if (!((event.keyCode > 47 && event.keyCode < 58) || (event.keyCode > 95 && event.keyCode < 106) || (objval.length > 13))) {
                        event.preventDefault();
                    } else {
                        if (objval.length == 0) {
                            $(this).val(objval + '(');
                            alert(objval + '(');
                        } else if (objval.length == 4) {
                            $(this).val(objval + ') ');
                            alert(objval + ') ');
                        } else if (objval.length == 9) {
                            $(this).val(objval + '-');
                            alert(objval + '-');
                        } else if (objval.length >= 14) {
                            if (event.keyCode == 9) {
                                return;
                            } else {
                                event.preventDefault();
                            }
                        }
                    }
                }
            });

            $('#phone').on('keydown', function (event) {

                var objVal = $(this).val();
                if(objVal.length < 14)
                {
                    validateCallerForm(objVal + String.fromCharCode((96 <= event.keyCode && event.keyCode <= 105)? event.keyCode-48 : event.keyCode));
                }
            });

            //Validates proper phone format, true if valid phone number, false otherwise
            function isValidPhoneNumber(elementValue) {
                var numberPattern = /^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/;
                return numberPattern.test(elementValue);
            }

            //validates entire caller form, also updates css classes for proper response
            function validateCallerForm(PhoneNumber) {

                if (isValidPhoneNumber(PhoneNumber)) {
                    alert("true");
                } else {
                    alert("false");
                }

            }
        </script>
    </body>
</html>

给正确答案的人 +50 赏金

【问题讨论】:

  • 您是否考虑过在blur 而不是keydown 上应用该格式?作为一个用户,我发现我输入的内容被重新格式化很烦人(即使它可以工作)。
  • 不,因为他们想要的是在输入时重新格式化数字。 :(

标签: javascript android jquery html webview


【解决方案1】:

您必须首先定义侦听器以进行键入和复制粘贴,如下所示(非必需):

$("#phone").keyup( function() {
    maskLine(this);
});
$("#phone").change( function() {
    maskLine(this);
});

然后,要管理光标位置,您必须缓存以前的电话号码,然后,如果需要,您可以比较差异并更新光标位置。 所以声明,你必须像这样声明一个全局数组:

var _cacheElementValues = new Array();

最后,您可以检查以下功能,它将您的掩码应用于电话号码字段并管理光标位置:

function maskLine( element ) {
    element = $(element);
    var maskedLine = '';
    var line = element.attr('value');

    // check the cache of the input and abord if no change since last treatment
    if (_cacheElementValues[element.attr('id')] != undefined && _cacheElementValues[element.attr('id')] == line) {
        return;
    }
    line = line.replace(/\D/g, ''); // remove all characters != digits
    line = line.substring(0, 10);
    if (line != '') {
        // apply mask
        if (line.length <= 2 ) {
            maskedLine = "(" + line;
        } else if (line.length < 6) {
            maskedLine = line.replace(/^([0-9]{3})([0-9]{0,3})/g, '($1) $2');
        } else {
            // mask : '(XXX) XXX-XXXX'
            maskedLine = line.replace(/^([0-9]{3})([0-9]{3})([0-9]{0,4})/g, '($1) $2-$3');
        }        
    }

    // define cursor position at the end of the input by default
    var pos = maskedLine.length;

    // Change cursor placement if necessary
    if (typeof element[0].selectionStart != 'undefined') {
        var start = element[0].selectionStart;
        var end   = element[0].selectionEnd;
        var insText = element[0].value.substring(start, end);

        // get current cursor placement
        if (insText.length == 0) {
            pos = start;
        } else {
            pos = start + insText.length;
        }

        // find how many digits typing since last mask application
        var previousLength = 0;
        if (_cacheElementValues[element.attr('id')] != undefined) {
            previousLength = _cacheElementValues[element.attr('id')].replace(/\s/g, '').length;
        }
        var diff = maskedLine.replace(/\s/g, '').length - previousLength;

        // if sum of new typing digit is > 0 : we change cursor placement
        if (diff > 0) {
            pos += (diff - 1) + Math.round((diff-1)/3);
            if (pos%6 == 0 && maskedLine.length >= pos+1) pos++;
        }
    }

    // update input data & cache
    element.val(maskedLine);
    _cacheElementValues[element.attr('id')] = maskedLine;

    // update cursor placement
    element[0].selectionStart = element[0].selectionEnd = pos;    
}

你可以在 jsFiddle 上找到这个例子:http://jsfiddle.net/UE9LB/5/

我希望这个小小的解释可以解决你的问题;) 享受吧!

ps:我为我糟糕的英语道歉:s

【讨论】:

  • 感谢您的回答,但它不适用于 Android。我尝试输入第一个数字“9”并呈现“(9”但光标位于“(”和“9”的中间。
  • @JeffRobertDgala 您是否尝试记录光标检测到的位置?知道为什么位置不好。或许,不是位置检测,而是新位置的更新。
【解决方案2】:

我建议至少从现有插件开始,而不是通过您自己孤立的几轮解决问题。

http://digitalbush.com/projects/masked-input-plugin/

https://github.com/igorescobar/jQuery-Mask-Plugin

【讨论】:

  • 感谢您的回答,我尝试了上述插件,但没有成功。
【解决方案3】:

简短的回答是设置输入元素的selectionStartselectionEnd 属性。格式化值后,将这些属性设置为 this.value.length

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

但是,当光标不在文本末尾时,您会遇到麻烦。例如,用户手动将光标定位到文本内的某个位置。为防止光标跳到末尾,需要在格式化输入前检测光标位置,格式化后将光标放回合适的位置。

编辑:This jsFiddle 可能会帮助您入门,但还不够完美。

【讨论】:

    【解决方案4】:

    我重写了#phone keydown 事件的代码,这将适用于 iPhone、Android、webkit 浏览器。

    $('#phone').on('keydown', function (event) {
        if (event.keyCode == 8 || event.keyCode == 37 || event.keyCode == 39) {
            // ignore if BKSPCE, left arrow, or right arrow
        } else {
            // validate if anything else
            inputval = $(this).val();
            var string = inputval.replace(/[^0-9]/g, "");
            var first3 = string.substring(0,3);
            var next3 = string.substring(3,6);
            var next4 = string.substring(6,10);
            var string = ("(" + first3 + ") " + next3 + "-" + next4);
            $(this).val(string);
        }
    });
    

    【讨论】:

    • 我认为这更好地解释了为什么第一个代码不起作用以及为什么这个重写版本可以。
    猜你喜欢
    • 2016-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多