<input type="tel">

类型为tel的<input>元素用于允许用户输入和编辑电话号码。与<input type="email">和<input type="url">不同,在提交表单之前,输入值不会自动验证为特定格式,因为全球各地电话号码的格式差异很大。

试一试

尽管类型为tel的输入在功能上与标准的text输入相同,但它们确实具有实用价值;其中最明显的用途是移动浏览器(尤其是在手机上)可能会选择显示一个针对电话号码输入优化的自定义键盘。为电话号码使用特定的输入类型还可以使添加自定义验证和处理电话号码更加方便。

注意:不支持类型tel的浏览器将回退为标准的<input type="text">输入。

<input>元素的<input#value>属性包含一个字符串,该字符串表示电话号码或为空字符串("")。

其他属性

除了适用于所有<input>元素(无论其类型如何)的属性外,电话号码输入还支持以下属性。

list

list 属性的值是同一文档中<datalist>元素的<id>。<datalist>提供一个预定义值的列表,以建议用户为此输入使用。列表中与<type>不兼容的任何值都不会包含在建议选项中。提供的这些值是建议,不是强制要求:用户可以选择此预定义列表中的值,也可以提供其他值。

maxlength

用户可以在电话号码字段中输入的最大字符串长度(以 UTF-16 代码单元计量)。这必须是 0 或更高的整数值。如果未指定maxlength或指定了无效值,则电话号码字段没有最大长度。此值还必须大于或等于minlength的值。

如果输入到字段中的文本长度超过maxlength UTF-16 代码单元,则输入将无法通过<constraint validation>。仅当用户更改值时才会应用约束验证。

minlength

用户可以在电话号码字段中输入的最小字符串长度(以 UTF-16 代码单元计量)。这必须是非负整数值,且小于或等于maxlength指定的值。如果未指定minlength或指定了无效值,则电话号码输入没有最小长度。

如果输入到字段中的文本长度少于minlength UTF-16 代码单元,则电话号码字段将无法通过<constraint validation>。仅当用户更改值时才会应用约束验证。

pattern

如果指定了pattern属性,则它是一个正则表达式,输入的<value>必须与该正则表达式匹配,才能通过<constraint validation>。它必须是有效的 JavaScript 正则表达式,与<RegExp>类型使用的正则表达式相同,并在我们的<正则表达式指南>中进行了说明;编译正则表达式时会指定'u'标志,以便将模式视为 Unicode 代码点的序列,而不是<ASCII>。模式文本周围不应指定正斜杠。

如果未指定或指定了无效的模式,则不会应用任何正则表达式,并且此属性将完全被忽略。

注意:使用<title>属性指定大多数浏览器将显示为工具提示的文本,以解释匹配模式的要求。您还应该在附近包含其他解释性文本。

有关详细信息和示例,请参阅下面的<模式验证>。

placeholder

placeholder属性是一个字符串,它向用户简要提示该字段需要哪种信息。它应该是一个单词或短语,用于演示预期的数据类型,而不是解释性消息。文本不得包含回车符或换行符。

如果控件的内容具有一个方向性(<LTR>或<RTL>),但需要以相反的方向性显示占位符,则可以使用 Unicode 双向算法格式化字符来覆盖占位符中的方向性;有关更多信息,请参阅<如何使用 Unicode 控制字符进行双向文本>。

注意: 尽可能避免使用placeholder属性。它在语义上不如其他解释表单的方式有用,并且可能导致内容出现意外的技术问题。有关更多信息,请参阅<input>标签

readonly

一个布尔属性,如果存在,则表示此字段不能由用户编辑。但是,它的value仍然可以通过JavaScript代码直接设置HTMLInputElementvalue属性来更改。

注意: 由于只读字段不能有值,因此required对也指定了readonly属性的输入没有任何影响。

size

size属性是一个数值,指示输入字段应有多宽(以字符为单位)。该值必须大于零的数字,默认值为20。由于字符宽度各不相同,因此这可能不准确,也不应依赖于此;根据字符和字体(正在使用的font设置),生成的输入可能比指定的字符数窄或宽。

不会限制用户可以在字段中输入多少个字符。它仅指定大约一次可以看到多少个字符。要设置输入数据长度的上限,请使用maxlength属性。

非标准属性

以下非标准属性可用于电话号码输入字段。作为一般规则,除非无法避免,否则应避免使用它们。

autocorrect

autocorrect属性是Safari扩展,它是一个字符串,指示在用户编辑此字段时是否激活自动更正。允许的值为

on

启用自动更正错别字,以及处理任何已配置的文本替换。

off

禁用自动更正和文本替换。

使用电话输入

电话号码是在网络上非常普遍收集的一种数据类型。例如,在创建任何类型的注册或电子商务网站时,您可能都需要询问用户电话号码,无论出于业务目的还是紧急联系目的。鉴于电话号码输入的普遍性,不幸的是,没有一个“一劳永逸”的解决方案可以用于验证电话号码。

幸运的是,您可以考虑您自己网站的要求并自行实现适当级别的验证。有关详细信息,请参阅下面的验证

自定义键盘

<input type="tel">的主要优势之一是它会导致移动浏览器显示一个特殊的键盘来输入电话号码。例如,以下是几个设备上的键盘外观。

Firefox for Android WebKit iOS (Safari/Chrome/Firefox)
Firefox for Android screen shot Firefox for iOS screenshot

一个简单的tel输入

在最基本的形式中,tel输入可以这样实现

html
<label for="telNo">Phone number:</label>
<input id="telNo" name="telNo" type="tel" />

这里没有任何神奇的操作。当提交到服务器时,上面输入的数据将表示为,例如,telNo=+12125553151

占位符

有时提供一个上下文提示以说明输入数据应采用什么形式非常有用。如果页面设计没有为每个<input>提供描述性标签,这尤其重要。这就是占位符的用武之地。占位符是一个值,它通过显示有效值的示例来演示value应采用的形式,当元素的value""时,它会显示在编辑框内。一旦在框中输入数据,占位符就会消失;如果清空该框,占位符将重新出现。

这里,我们有一个带有占位符123-4567-8901tel输入。请注意,当您操作编辑字段的内容时,占位符是如何消失和重新出现的。

html
<input id="telNo" name="telNo" type="tel" placeholder="123-4567-8901" />

控制输入大小

您可以不仅控制输入框的物理长度,还可以控制输入文本本身的最小和最大允许长度。

物理输入元素大小

可以使用size属性控制输入框的物理大小。使用它,您可以指定输入框一次可以显示多少个字符。例如,在此示例中,tel编辑框宽20个字符

html
<input id="telNo" name="telNo" type="tel" size="20" />

元素值长度

size与输入电话号码的长度限制是分开的。您可以使用minlength属性指定输入电话号码的最小长度(以字符为单位);类似地,使用maxlength设置输入电话号码的最大长度。

以下示例创建了一个20个字符宽的电话号码输入框,要求内容不少于9个字符,不多于14个字符。

html
<input
  id="telNo"
  name="telNo"
  type="tel"
  size="20"
  minlength="9"
  maxlength="14" />

注意: 上述属性确实会影响验证——如果值的长度小于9个字符或大于14个字符,则上述示例的输入将被视为无效。大多数浏览器甚至不允许您输入超过最大长度的值。

提供默认选项

使用value属性提供单个默认值

与往常一样,您可以通过设置tel输入框的value属性来为其提供默认值

html
<input id="telNo" name="telNo" type="tel" value="333-4444-4444" />

提供建议值

更进一步,您可以提供一个用户可以从中选择的默认电话号码值列表。为此,请使用list属性。这不会限制用户只能选择这些选项,但确实允许他们更快地选择常用的电话号码。这也为autocomplete提供提示。list属性指定<datalist>元素的ID,而<datalist>元素又包含每个建议值的<option>元素;每个optionvalue是电话号码输入框对应的建议值。

html
<label for="telNo">Phone number: </label>
<input id="telNo" name="telNo" type="tel" list="defaultTels" />

<datalist id="defaultTels">
  <option value="111-1111-1111"></option>
  <option value="122-2222-2222"></option>
  <option value="333-3333-3333"></option>
  <option value="344-4444-4444"></option>
</datalist>

有了<datalist>元素及其<option>,浏览器将提供指定的作为电话号码的潜在值;这通常以包含建议的弹出窗口或下拉菜单的形式呈现。虽然特定用户体验可能因浏览器而异,但通常点击编辑框会显示建议电话号码的下拉列表。然后,当用户键入时,列表将调整为仅显示过滤后的匹配值。每个键入的字符都会缩小列表范围,直到用户进行选择或键入自定义值。

以下是它可能看起来的样子截图

An input box has focus with a blue focus ring. The input has a drop-down menu showing four phone numbers the user can select.

验证

正如我们之前所讨论的,为电话号码提供一个一劳永逸的客户端验证解决方案非常困难。那么我们能做什么呢?让我们考虑一些选项。

警告: HTML表单验证不是服务器端脚本的替代品,这些脚本在允许数据进入数据库之前确保输入的数据格式正确。对于某人来说,调整HTML以允许他们绕过验证或完全删除验证,这太容易了。某人也可以完全绕过您的HTML并将数据直接提交到您的服务器。如果您的服务器端代码未能验证它接收到的数据,则当格式不正确的(或太大、类型错误等)数据输入到您的数据库时,可能会发生灾难。

使电话号码成为必填项

您可以使用required属性,使空输入无效,并且不会提交到服务器。例如,让我们使用以下HTML

html
<form>
  <div>
    <label for="telNo">Enter a telephone number (required): </label>
    <input id="telNo" name="telNo" type="tel" required />
    <span class="validity"></span>
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>

并且让我们包含以下CSS以使用复选标记突出显示有效条目,并使用叉号突出显示无效条目

css
div {
  margin-bottom: 10px;
  position: relative;
}

input[type="number"] {
  width: 100px;
}

input + span {
  padding-right: 30px;
}

input:invalid + span::after {
  position: absolute;
  content: "✖";
  padding-left: 5px;
  color: #8b0000;
}

input:valid + span::after {
  position: absolute;
  content: "✓";
  padding-left: 5px;
  color: #009000;
}

输出如下所示

模式验证

如果您想进一步限制输入的数字,以便它们也必须符合特定模式,则可以使用pattern属性,该属性将其值作为正则表达式,输入的值必须与之匹配。

在此示例中,我们将使用与之前相同的CSS,但我们的HTML更改为如下所示

html
<form>
  <div>
    <label for="telNo">
      Enter a telephone number (in the form xxx-xxx-xxxx):
    </label>
    <input
      id="telNo"
      name="telNo"
      type="tel"
      required
      pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" />
    <span class="validity"></span>
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>

请注意,除非匹配模式xxx-xxx-xxxx,否则输入的值将被报告为无效;例如,41-323-421将不被接受。800-MDN-ROCKS也不会被接受。但是,865-555-6502将被接受。这种特定的模式显然仅对某些地区有用——在实际应用程序中,您可能需要根据用户的地区更改使用的模式。

示例

在此示例中,我们提供了一个简单的界面,其中包含一个<select>元素,允许用户选择他们所在的国家/地区,以及一组<input type="tel">元素,允许他们输入电话号码的每个部分;没有理由为什么您不能有多个tel输入。

每个输入都有一个placeholder属性,向有视力障碍的用户提示应输入的内容,一个pattern属性,用于强制执行所需部分的特定字符数,以及一个aria-label属性,用于包含提示以向屏幕阅读器用户朗读应输入的内容。

html
<form>
  <div>
    <label for="country">Choose your country:</label>
    <select id="country" name="country">
      <option>UK</option>
      <option selected>US</option>
      <option>Germany</option>
    </select>
  </div>
  <div>
    <p>Enter your telephone number:</p>
    <span class="areaDiv">
      <input
        id="areaNo"
        name="areaNo"
        type="tel"
        required
        placeholder="Area code"
        pattern="[0-9]{3}"
        aria-label="Area code" />
      <span class="validity"></span>
    </span>
    <span class="number1Div">
      <input
        id="number1"
        name="number1"
        type="tel"
        required
        placeholder="First part"
        pattern="[0-9]{3}"
        aria-label="First part of number" />
      <span class="validity"></span>
    </span>
    <span class="number2Div">
      <input
        id="number2"
        name="number2"
        type="tel"
        required
        placeholder="Second part"
        pattern="[0-9]{4}"
        aria-label="Second part of number" />
      <span class="validity"></span>
    </span>
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>

JavaScript相对简单——它包含一个onchange事件处理程序,当<select>值更改时,它会更新<input>元素的patternplaceholderaria-label以适合该国家/地区的电话号码格式。

js
const selectElem = document.querySelector("select");
const inputElems = document.querySelectorAll("input");

selectElem.onchange = () => {
  for (let i = 0; i < inputElems.length; i++) {
    inputElems[i].value = "";
  }

  if (selectElem.value === "US") {
    inputElems[2].parentNode.style.display = "inline";

    inputElems[0].placeholder = "Area code";
    inputElems[0].pattern = "[0-9]{3}";

    inputElems[1].placeholder = "First part";
    inputElems[1].pattern = "[0-9]{3}";
    inputElems[1].setAttribute("aria-label", "First part of number");

    inputElems[2].placeholder = "Second part";
    inputElems[2].pattern = "[0-9]{4}";
    inputElems[2].setAttribute("aria-label", "Second part of number");
  } else if (selectElem.value === "UK") {
    inputElems[2].parentNode.style.display = "none";

    inputElems[0].placeholder = "Area code";
    inputElems[0].pattern = "[0-9]{3,6}";

    inputElems[1].placeholder = "Local number";
    inputElems[1].pattern = "[0-9]{4,8}";
    inputElems[1].setAttribute("aria-label", "Local number");
  } else if (selectElem.value === "Germany") {
    inputElems[2].parentNode.style.display = "inline";

    inputElems[0].placeholder = "Area code";
    inputElems[0].pattern = "[0-9]{3,5}";

    inputElems[1].placeholder = "First part";
    inputElems[1].pattern = "[0-9]{2,4}";
    inputElems[1].setAttribute("aria-label", "First part of number");

    inputElems[2].placeholder = "Second part";
    inputElems[2].pattern = "[0-9]{4}";
    inputElems[2].setAttribute("aria-label", "Second part of number");
  }
};

示例如下所示

这是一个有趣的想法,它展示了解决处理国际电话号码问题的潜在方案。当然,您需要扩展示例以提供可能每个国家/地区的正确模式,这将是一项繁重的工作,并且仍然无法保证用户会正确输入他们的号码。

这让人不禁怀疑,当您只需让用户以任何他们想要的格式在客户端输入他们的号码,然后在服务器端验证和清理它时,是否值得在客户端花费如此多的精力。但这个选择由您决定。

技术总结

表示电话号码的字符串,或者为空
事件 changeinput
支持的常用属性 autocompletelistmaxlengthminlengthpatternplaceholderreadonlysize
IDL 属性 listselectionStartselectionEndselectionDirectionvalue
DOM 接口

HTMLInputElement

方法 select()setRangeText()setSelectionRange()
隐式 ARIA 角色 没有list属性:textbox list属性:combobox

规范

规范
HTML 标准
# telephone-state-(type=tel)

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅