使用纯JavaScript将用户键入的电话号码格式化

时间:2023-01-14 14:28:56

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

5 个解决方案

#1


New ES6 Answer

You can still do this using some simple JavaScript.

您仍然可以使用一些简单的JavaScript来完成此操作。

HTML

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

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 carat 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

You can do this using a quick javascript function.

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

如果你的HTML看起来像:

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')。 .replace(/ \ d /克, '');

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/

#2


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;
});

#3


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.

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

#4


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

#5


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" />

#1


New ES6 Answer

You can still do this using some simple JavaScript.

您仍然可以使用一些简单的JavaScript来完成此操作。

HTML

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

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 carat 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

You can do this using a quick javascript function.

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

如果你的HTML看起来像:

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')。 .replace(/ \ d /克, '');

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/

#2


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;
});

#3


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.

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

#4


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

#5


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" />