使用纯 JavaScript 在用户键入时格式化电话号码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30058927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:35:34  来源:igfitidea点击:

Format a phone number as a user types using pure JavaScript

javascriptformatting

提问by Legendary_Linux

I've got an input field in the body of my document, and I need to format it as the user types. It should have parenthesis around the area code and a dash between the three and four digits after that.

我的文档正文中有一个输入字段,我需要将其格式化为用户类型。它应该在区号周围加上括号,之后的三到四位数字之间应该有一个破折号。

Ex: (123) 456 - 7890

前任: (123) 456 - 7890

As the user types it should look something like:

当用户键入时,它应该类似于:

(12
(123)
(123) 456
(123) 456 - 78
(123) 456 - 7890

(12
(123)
(123) 456
(123) 456 - 78
(123) 456 - 7890

回答by Legendary_Linux

New ES6 Answer

新的 ES6 答案

You can still do this using some simple JavaScript.

您仍然可以使用一些简单的 JavaScript 来做到这一点。

HTML

HTML

<input id="phoneNumber" maxlength="16" />

<input id="phoneNumber" maxlength="16" />

JavaScript (ES6)

JavaScript (ES6)

const isNumericInput = (event) => {
    const key = event.keyCode;
    return ((key >= 48 && key <= 57) || // Allow number line
        (key >= 96 && key <= 105) // Allow number pad
    );
};

const isModifierKey = (event) => {
    const key = event.keyCode;
    return (event.shiftKey === true || key === 35 || key === 36) || // Allow Shift, Home, End
        (key === 8 || key === 9 || key === 13 || key === 46) || // Allow Backspace, Tab, Enter, Delete
        (key > 36 && key < 41) || // Allow left, up, right, down
        (
            // Allow Ctrl/Command + A,C,V,X,Z
            (event.ctrlKey === true || event.metaKey === true) &&
            (key === 65 || key === 67 || key === 86 || key === 88 || key === 90)
        )
};

const enforceFormat = (event) => {
    // Input must be of a valid number format or a modifier key, and not longer than ten digits
    if(!isNumericInput(event) && !isModifierKey(event)){
        event.preventDefault();
    }
};

const formatToPhone = (event) => {
    if(isModifierKey(event)) {return;}

    // I am lazy and don't like to type things more than once
    const target = event.target;
    const input = target.value.replace(/\D/g,'').substring(0,10); // First ten digits of input only
    const zip = input.substring(0,3);
    const middle = input.substring(3,6);
    const last = input.substring(6,10);

    if(input.length > 6){target.value = `(${zip}) ${middle} - ${last}`;}
    else if(input.length > 3){target.value = `(${zip}) ${middle}`;}
    else if(input.length > 0){target.value = `(${zip}`;}
};

const inputElement = document.getElementById('phoneNumber');
inputElement.addEventListener('keydown',enforceFormat);
inputElement.addEventListener('keyup',formatToPhone);

And if you'd like to fiddle with it:
https://jsfiddle.net/rafj3md0/

如果你想摆弄它:https:
//jsfiddle.net/rafj3md0/

Disclaimer:
It's worth noting this gets a little weird if you attempt to modify the middle of the number because of the way browsers handle caret placement after you set an element's value. Solving that problem is doable, but would require more time than I have right now, and there are libraries out there that handle things like that.

免责声明:
值得注意的是,如果您尝试修改数字的中间位置,这会变得有点奇怪,因为浏览器在设置元素值后处理插入符号位置的方式。解决这个问题是可行的,但需要比我现在更多的时间,而且有一些库可以处理这样的事情。



Old ES5 Answer

旧的 ES5 答案

您可以使用快速 javascript 函数来执行此操作。

If your HTML looks like:
<input type="text" id="phoneNumber"/>

如果您的 HTML 如下所示:
<input type="text" id="phoneNumber"/>

Your JavaScript function can simply be:

您的 JavaScript 函数可以是:

// A function to format text to look like a phone number
function phoneFormat(input){
        // Strip all characters from the input except digits
        input = input.replace(/\D/g,'');

        // Trim the remaining input to ten characters, to preserve phone number format
        input = input.substring(0,10);

        // Based upon the length of the string, we add formatting as necessary
        var size = input.length;
        if(size == 0){
                input = input;
        }else if(size < 4){
                input = '('+input;
        }else if(size < 7){
                input = '('+input.substring(0,3)+') '+input.substring(3,6);
        }else{
                input = '('+input.substring(0,3)+') '+input.substring(3,6)+' - '+input.substring(6,10);
        }
        return input; 
}

Of course, you'll need an event listener:

当然,你需要一个事件监听器:

document.getElementById('phoneNumber').addEventListener('keyup',function(evt){
        var phoneNumber = document.getElementById('phoneNumber');
        var charCode = (evt.which) ? evt.which : evt.keyCode;
        phoneNumber.value = phoneFormat(phoneNumber.value);
});

And unless you're okay storing phone numbers as formatted strings (I don't recommend this), you'll want to purge the non-numeric characters before submitting the value with something like:
document.getElementById('phoneNumber').value.replace(/\D/g,'');

除非您可以将电话号码存储为格式化字符串(我不建议这样做),否则您需要在提交值之前清除非数字字符,例如:
document.getElementById('phoneNumber').value.replace(/\D/g,'');

If you'd like to see this in action with bonus input filtering, check out this fiddle:
http://jsfiddle.net/rm9vg16m/

如果您想通过奖金输入过滤看到这一点,请查看此小提琴:http:
//jsfiddle.net/rm9vg16m/

// Format the phone number as the user types it
document.getElementById('phoneNumber').addEventListener('keyup', function(evt) {
  var phoneNumber = document.getElementById('phoneNumber');
  var charCode = (evt.which) ? evt.which : evt.keyCode;
  phoneNumber.value = phoneFormat(phoneNumber.value);
});

// We need to manually format the phone number on page load
document.getElementById('phoneNumber').value = phoneFormat(document.getElementById('phoneNumber').value);

// A function to determine if the pressed key is an integer
function numberPressed(evt) {
  var charCode = (evt.which) ? evt.which : evt.keyCode;
  if (charCode > 31 && (charCode < 48 || charCode > 57) && (charCode < 36 || charCode > 40)) {
    return false;
  }
  return true;
}

// A function to format text to look like a phone number
function phoneFormat(input) {
  // Strip all characters from the input except digits
  input = input.replace(/\D/g, '');

  // Trim the remaining input to ten characters, to preserve phone number format
  input = input.substring(0, 10);

  // Based upon the length of the string, we add formatting as necessary
  var size = input.length;
  if (size == 0) {
    input = input;
  } else if (size < 4) {
    input = '(' + input;
  } else if (size < 7) {
    input = '(' + input.substring(0, 3) + ') ' + input.substring(3, 6);
  } else {
    input = '(' + input.substring(0, 3) + ') ' + input.substring(3, 6) + ' - ' + input.substring(6, 10);
  }
  return input;
}
Enter a phone number here: <input type="text" id="phoneNumber" onkeypress="return numberPressed(event);" />

回答by Motate

Earlier answers didn't consider what happens when a user makes a mistake and deletes some of the entered digits.

较早的答案没有考虑当用户犯错并删除一些输入的数字时会发生什么。

For those looking for a jQuery solution, this reformats on every keyup event, and removes the additional characters and whitespace when the user is editing the number.

对于那些寻找 jQuery 解决方案的人来说,这会在每个 keyup 事件上重新格式化,并在用户编辑数字时删除额外的字符和空格。

$('#phone').keyup(function(e){
    var ph = this.value.replace(/\D/g,'').substring(0,10);
    // Backspace and Delete keys
    var deleteKey = (e.keyCode == 8 || e.keyCode == 46);
    var len = ph.length;
    if(len==0){
        ph=ph;
    }else if(len<3){
        ph='('+ph;
    }else if(len==3){
        ph = '('+ph + (deleteKey ? '' : ') ');
    }else if(len<6){
        ph='('+ph.substring(0,3)+') '+ph.substring(3,6);
    }else if(len==6){
        ph='('+ph.substring(0,3)+') '+ph.substring(3,6)+ (deleteKey ? '' : '-');
    }else{
        ph='('+ph.substring(0,3)+') '+ph.substring(3,6)+'-'+ph.substring(6,10);
    }
    this.value = ph;
});

回答by Rey

I'm not a fan of the slicing stuff. I'd advise using .replace(), pass it a regex, capture the pieces of the phone number, and then output it the way you need it. If you can read regex, it's a much better programmatic way to approach the issue, and dead simple to alter the format.

我不喜欢切片的东西。我建议使用 .replace(),将其传递给正则表达式,捕获电话号码的部分,然后按照您需要的方式输出。如果您可以阅读正则表达式,那么这是一种更好的编程方式来解决该问题,并且更改格式非常简单。

var phoneNumber = "1234567899";

var formatted = phoneNumber.replace(/(\d{1,2})(\d{1})?(\d{1,3})?(\d{1,4})?/, function(_, p1, p2, p3, p4){
  let output = ""
  if (p1) output = `(${p1}`;
  if (p2) output += `${p2})`;
  if (p3) output += ` ${p3}`
  if (p4) output += ` ${p4}`
  return output;
});

Note: I haven't added any sort of whitespace, non number stripping but you can add that as well.

注意:我没有添加任何类型的空格,非数字剥离,但您也可以添加。

回答by venkat7668

let telEl = document.querySelector('#phoneNum')

telEl.addEventListener('keyup', (e) => {
  let val = e.target.value;
  e.target.value = val
    .replace(/\D/g, '')
    .replace(/(\d{1,4})(\d{1,3})?(\d{1,3})?/g, function(txt, f, s, t) {
      if (t) {
        return `(${f}) ${s}-${t}`
      } else if (s) {
        return `(${f}) ${s}`
      } else if (f) {
        return `(${f})`
      }
    });
})
Phone Number: <input type="text" id="phoneNum" maxlength="14" />

回答by paulby

To add some additional ease for the user, I'd actually update the string to automatically include a ")" or "-" as the user reaches certain characters, to prevent them from adding, say two dashes. (555)555--5555

为了给用户增加一些额外的便利,我实际上会更新字符串以在用户到达某些字符时自动包含“)”或“-”,以防止它们添加,比如两个破折号。(555)555--5555

if(size === 0) {
    input = input;
} 
else if (size === 3) {
    input = '('+input.substring(0,3)+') '
}
else if (size < 4) {
    input = '('+input;
}
else if (size === 6) {
    input = '('+input.substring(0,3)+') '+input.substring(3,6)+' -';
}
else if (size > 6) {
    input = '('+input.substring(0,3)+') '+input.substring(3,6)+' - '+input.substring(6,10);
}
return input