[: currentTime | date:'mm:ss' :] [: timeLeft | date:'mm:ss' :]

示例参考

结果
HTML
CSS
JS
运行
整页预览
<main>
  <h2>添加用户</h2>
  <form>
    <label>
      姓名
      <input type="text" name="name">
    </label>
    <label>
      性别
      <input type="text" name="gender">
    </label>
    <label>
      文化分
      <input type="text" name="score">
    </label>
    <label>
      平时分
      <input type="text" name="quality">
    </label>
    <div class="error" hidden></div>
    <button type="submit">提交</button>
  </form>
</main>
:root {
  font-family: sans-serif;
  color: #444;
  font-size: 15px;
}

body {
  margin: 0;
}

input, button {
  padding: .6rem;
  border: 1px solid rgba(0, 0, 0, .1);
  outline: 0;
  font-size: .8rem;
}

input:focus,
button:focus {
  outline: 2px solid #cfa8ff;
}

form label,
form input {
  display: block;
  width: 100%;
  margin: .3rem 0;
}

form label,
.error {
  margin-bottom: 1rem;
}

main {
  max-width: 30rem;
  margin-left: auto;
  margin-right: auto;
  padding: 10px;
}

button[type=submit] {
  width: 100%;
  color: #fff;
  background: #7326d1;
}

table {
  border-collapse: collapse;
  width: 100%;
}

table > * {
  text-align: left;
}

table th,
table td {
  padding: .6rem;
}

table thead {
  border-bottom: 3px solid rgba(0, 0, 0, .1);
}

table td {
  border-bottom: 1px solid rgba(0, 0, 0, .1);
}

table tr:last-of-type td {
  border: 0;
}

tbody tr:hover {
  background: #f4ebff;
}

[hidden] {
  display: none !important;
}

.error {
  padding: 1em;
  color: #b10;
  background: pink;
}
/*
|--------------------------------------------------------------------------
| 视图部分
|--------------------------------------------------------------------------
*/

class UserForm {
  /**
   * @param {string} selector 表单选择器
   * @param {string} errorSelector 错误信息容器的选择器
   */
  constructor (selector, errorSelector = '.error') {
    // 选中公用元素
    this.el      = document.querySelector(selector);
    this.elError = this.el.querySelector(errorSelector);
    // 绑定必要的初始事件
    this.bindEvents();
  }

  reset () {
    this.el.reset();
  }

  bindEvents () {
    this.bindSubmit();
    this.bindInput();
  }

  bindInput () {
    let form = this.el;
    form.addEventListener('keyup', e => {
      if (e.key == 'Enter')
        return;

      this.elError.hidden = true;
    });
  }

  bindSubmit () {
    let form = this.el;
    let q    = form.querySelector.bind(form);

    this.el.addEventListener('submit', e => {
      e.preventDefault();
      let name    = q('[name=name]').value;
      let gender  = q('[name=gender]').value;
      let score   = q('[name=score]').value;
      let quality = q('[name=quality]').value;

      let builder = new Builder();

      try {
        builder.setName(name);
        builder.setGender(gender);
        builder.setScore(score);
        builder.setQuality(quality);
      } catch (e) {
        let error       = this.elError;
        error.hidden    = false;
        error.innerHTML = e;
        return;
      }

      console.log(builder.build());
      this.reset();
    });
  }
}

/*
|--------------------------------------------------------------------------
| 数据部分
|--------------------------------------------------------------------------
*/

class User {}

class Builder {
  constructor () {
    this.instance = new User;
  }

  setName (name) {
    let maxLength = 10;
    if (!name)
      throw '姓名不可为空';

    if (name.length > maxLength)
      throw `姓名长度不可大于${maxLength}`;

    this.instance.name = name;
    return this;
  }

  setGender (gender) {
    let genderSet = [ '男', '女' ];

    if (genderSet.indexOf(gender) < 0)
      throw '别闹,不合法的性别';

    this.instance.gender = gender;
    return this;
  }

  setScore (score) {
    if (!this.validNumber(score))
      throw '别闹,文化分应该是阿拉伯数字';

    this.instance.score = parseFloat(score);
    return this;
  }

  setQuality (quality) {
    if (!this.validNumber(quality))
      throw '别闹,平时分应该是阿拉伯数字';

    this.instance.quality = parseFloat(quality);
    return this;
  }

  validNumber (val) {
    return val === 0 || parseFloat(val);
  }

  build () {
    return this.instance;
  }
}

/*
|--------------------------------------------------------------------------
| 业务逻辑
|--------------------------------------------------------------------------
| description
*/

new UserForm('form');
登录后评论