HTML attachInternals自定义元素原生表单特性实例页面

回到相关文章 »

效果:

同意协议

代码:

HTML代码:
<form id="form" action="" novalidate>
    <ui-checkbox value="1" name="agree" required tabindex="-1"></ui-checkbox> 同意协议
    <p>
        <button type="submit">提交</button>
    </p>
</form>
JS代码:
class UiCheckbox extends HTMLElement {
  static get formAssociated() {
    return true;
  }

  constructor() {
    super();
    this.internals = this.attachInternals();
    // 赋值,原生表单提交需要
    this.internals.setFormValue(this.value);
    
    this.addEventListener('click', () => {
        this.checked = !this.checked;    
    });
  }
  
  get checked () {
    return this.hasAttribute('checked');
  }
  
  set checked (val) {      
    return this.toggleAttribute('checked', val);
  }
  
  get value () {
    return this.getAttribute('value') || '';
  }
  
  set value (val) {
    this.internals.setFormValue(val);
    // 属性值跟着变化
    return this.setAttribute('value', val);
  }
}

customElements.define('ui-checkbox', UiCheckbox);

// 表单提交验证的处理
// 使用原生表单验证方法
form.addEventListener('submit', function (event) {
    event.preventDefault();
    // 自定义复选框元素
    const checkbox = this.querySelector('ui-checkbox');
    if (!checkbox.checked) {
        checkbox.internals.setValidity({ 
            valueMissing: true 
        }, '协议必须勾选');
        // 提示
        checkbox.internals.reportValidity();
    } else {
        checkbox.internals.setValidity({});
        // 触发原生提交
        this.submit();
    }
});
CSS代码:
/* 不重要,略 */