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

如何为密码输入框设置失焦触发的验证样式

问题

我有一个包含长度、大小写字母、数字、特殊字符等验证规则的密码输入框。当前验证逻辑为:输入符合要求时验证标签变绿,未满足要求时变红。但我希望仅在用户完成输入(离开输入框)后才应用这些样式:初始状态下所有验证标签为黑色,只有用户离开输入框后,才根据输入内容切换为绿色(符合规则)或红色(不符合规则)。

原代码如下:

import React from "react";

class Password extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      text: "",
      req: {
        len: "invalid",
        cap: "invalid",
        num: "invalid",
        spec: "invalid"
      }
    };
  }
  handleChange = (e) => {
    this.setState({ text: e.target.value });
  };
  render() {
    let reqState = {};

    reqState.len = this.state.text.length >= 7 ? "valid" : "invalid";
    reqState.cap = this.state.text.match(/[A-Z]/) ? "valid" : "invalid";
    reqState.low = this.state.text.match(/[a-z]/) ? "valid" : "invalid";
    reqState.num = this.state.text.match(/[0-9]/) ? "valid" : "invalid";
    reqState.spec = this.state.text.match(/[~!@#$%^&*\-_]/)
      ? "valid"
      : "invalid";

    return (
      <div style={styles.login}>
        <input
          type="password"
          style={styles.inputs}
          placeholder="Password"
          value={this.state.text}
          onChange={this.handleChange}
        />

        <h4>Password Requirements</h4>
        <div style={styles.reqs}>
          <ul style={styles.requirements}>
            <li style={styles[reqState.len]}>8-13 Characters</li>
            <li style={styles[reqState.cap]}>At least 1 Capitalcase</li>
            <li style={styles[reqState.low]}>At least 1 lowercase</li>
            <li style={styles[reqState.num]}>At least 1 number</li>
            <li style={styles[reqState.spec]}>At least 1 special character</li>
          </ul>
        </div>
      </div>
    );
  }
}

export default Password;
const styles = {
  login: {
    width: "75%"
  },
  inputs: {
    display: "block",
    margin: "0 auto",
    marginTop: "20px",
    padding: "12px",
    borderRadius: "0.5"
  },
  button: {
    padding: "16px",
    marginTop: "20px",
    backgroundColor: "#113163",
    color: "#efefef",
    fontSize: "large"
  },
  reqs: {
    margin: "0 auto",
    width: "60%"
  },
  requirements: {
    textAlign: "left"
  },
  valid: {
    color: "green"
  },
  invalid: {
    color: "red"
  }
};
解决方案

通过添加焦点状态标记,控制验证样式的触发时机,具体修改如下:

  1. 新增状态字段:在state中添加isBlurred,初始值为false,标记输入框是否已失去焦点
  2. 添加失焦处理方法:实现handleBlur,当输入框失去焦点时将isBlurred设为true
  3. 修改验证样式逻辑:仅当isBlurred为true时,才应用valid/invalid样式;否则使用默认黑色样式
  4. 新增默认样式:在styles中添加normal样式,用于初始状态的黑色文本

修改后的完整代码:

import React from "react";

class Password extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      text: "",
      isBlurred: false // 新增:标记输入框是否已失焦
    };
  }

  handleChange = (e) => {
    this.setState({ text: e.target.value });
  };

  // 新增:处理输入框失焦事件
  handleBlur = () => {
    this.setState({ isBlurred: true });
  };

  render() {
    let reqState = {};

    // 计算验证状态
    reqState.len = this.state.text.length >= 7 ? "valid" : "invalid";
    reqState.cap = this.state.text.match(/[A-Z]/) ? "valid" : "invalid";
    reqState.low = this.state.text.match(/[a-z]/) ? "valid" : "invalid";
    reqState.num = this.state.text.match(/[0-9]/) ? "valid" : "invalid";
    reqState.spec = this.state.text.match(/[~!@#$%^&*\-_]/)
      ? "valid"
      : "invalid";

    return (
      <div style={styles.login}>
        <input
          type="password"
          style={styles.inputs}
          placeholder="Password"
          value={this.state.text}
          onChange={this.handleChange}
          onBlur={this.handleBlur} // 绑定失焦事件
        />

        <h4>密码要求</h4>
        <div style={styles.reqs}>
          <ul style={styles.requirements}>
            {/* 根据isBlurred决定应用哪种样式 */}
            <li style={this.state.isBlurred ? styles[reqState.len] : styles.normal}>8-13个字符</li>
            <li style={this.state.isBlurred ? styles[reqState.cap] : styles.normal}>至少1个大写字母</li>
            <li style={this.state.isBlurred ? styles[reqState.low] : styles.normal}>至少1个小写字母</li>
            <li style={this.state.isBlurred ? styles[reqState.num] : styles.normal}>至少1个数字</li>
            <li style={this.state.isBlurred ? styles[reqState.spec] : styles.normal}>至少1个特殊字符</li>
          </ul>
        </div>
      </div>
    );
  }
}

export default Password;
const styles = {
  login: {
    width: "75%"
  },
  inputs: {
    display: "block",
    margin: "0 auto",
    marginTop: "20px",
    padding: "12px",
    borderRadius: "0.5"
  },
  button: {
    padding: "16px",
    marginTop: "20px",
    backgroundColor: "#113163",
    color: "#efefef",
    fontSize: "large"
  },
  reqs: {
    margin: "0 auto",
    width: "60%"
  },
  requirements: {
    textAlign: "left",
    listStyle: "none",
    paddingLeft: 0
  },
  valid: {
    color: "green"
  },
  invalid: {
    color: "red"
  },
  normal: { // 新增:初始状态的黑色文本
    color: "#000"
  }
};

优化后效果

优化后效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:43:16