You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Material毫秒时间输入在iOS端无法输入秒和毫秒的解决方法

解决iOS端Angular matInput time类型无法输入秒和毫秒的问题

iOS Safari的原生time类型输入控件存在实现限制,即使设置了step="0.001",也不会提供秒和毫秒的输入区域,只能输入小时和分钟。要解决这个问题,最可靠的方式是放弃原生time控件,改用自定义文本输入框并手动处理格式验证,具体实现如下:

方案1:自定义文本输入框(基础版)

模板代码

<mat-form-field appearance="fill" class="full-width">
  <mat-label>Lap time</mat-label>
  <input 
    matInput 
    required 
    name="lapTime" 
    [(ngModel)]="lap_time" 
    type="text" 
    placeholder="HH:mm:ss.SSS"
    (input)="formatLapTime($event)"
  />
  <mat-error *ngIf="!isValidLapTime(lap_time)">请输入有效格式(如 01:23:45.678)</mat-error>
</mat-form-field>

组件逻辑代码

lap_time: string = '';

// 实时格式化输入内容,限制合法字符与格式
formatLapTime(event: Event) {
  const input = event.target as HTMLInputElement;
  // 只保留数字、冒号和小数点
  let value = input.value.replace(/[^0-9:.]/g, '');
  
  // 按格式拆分并限制各部分长度:HH:mm:ss.SSS
  const parts = value.split(':');
  if (parts.length > 3) parts.splice(3); // 最多保留3段(时、分、秒+毫秒)
  
  // 限制小时为2位
  if (parts[0]) parts[0] = parts[0].slice(0, 2);
  // 限制分钟为2位
  if (parts[1]) parts[1] = parts[1].slice(0, 2);
  // 处理秒和毫秒:秒2位,毫秒3位
  if (parts[2]) {
    const secMs = parts[2].split('.');
    secMs[0] = secMs[0].slice(0, 2);
    if (secMs[1]) secMs[1] = secMs[1].slice(0, 3);
    parts[2] = secMs.join('.');
  }
  
  input.value = parts.join(':');
  this.lap_time = input.value;
}

// 验证输入格式是否符合 HH:mm:ss.SSS
isValidLapTime(value: string): boolean {
  if (!value) return false;
  const timeRegex = /^([0-1]\d|2[0-3]):([0-5]\d):([0-5]\d)\.\d{3}$/;
  return timeRegex.test(value);
}

方案2:结合响应式表单(更规范)

如果项目使用Angular响应式表单,可以配合表单验证器实现更严谨的校验:

组件逻辑代码

import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';

@Component({
  // 组件元数据...
})
export class LapTimeComponent {
  lapTimeForm = this.fb.group({
    lapTime: [
      '',
      [
        Validators.required,
        Validators.pattern(/^([0-1]\d|2[0-3]):([0-5]\d):([0-5]\d)\.\d{3}$/)
      ]
    ]
  });

  constructor(private fb: FormBuilder) {}

  formatLapTime(event: Event) {
    // 复用方案1中的格式化逻辑
    const input = event.target as HTMLInputElement;
    let value = input.value.replace(/[^0-9:.]/g, '');
    const parts = value.split(':');
    if (parts.length > 3) parts.splice(3);
    if (parts[0]) parts[0] = parts[0].slice(0, 2);
    if (parts[1]) parts[1] = parts[1].slice(0, 2);
    if (parts[2]) {
      const secMs = parts[2].split('.');
      secMs[0] = secMs[0].slice(0, 2);
      if (secMs[1]) secMs[1] = secMs[1].slice(0, 3);
      parts[2] = secMs.join('.');
    }
    input.value = parts.join(':');
    this.lapTimeForm.patchValue({ lapTime: input.value });
  }
}

模板代码

<mat-form-field appearance="fill" class="full-width">
  <mat-label>Lap time</mat-label>
  <input 
    matInput 
    formControlName="lapTime" 
    type="text" 
    placeholder="HH:mm:ss.SSS"
    (input)="formatLapTime($event)"
  />
  <mat-error *ngIf="lapTimeForm.get('lapTime')?.hasError('required')">此字段必填</mat-error>
  <mat-error *ngIf="lapTimeForm.get('lapTime')?.hasError('pattern')">请输入有效格式(如 01:23:45.678)</mat-error>
</mat-form-field>

补充说明

如果需要更友好的选择器体验(而非纯文本输入),可以自行实现弹窗式的时间选择组件,拆分出时、分、秒、毫秒的下拉选择项,不过开发量会相对较大。

内容的提问来源于stack exchange,提问作者Gabbodrummer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 15:25:38