1. 程式人生 > 實用技巧 >JS面向物件:簡單封裝表單

JS面向物件:簡單封裝表單

對於表單的操作,主要是使用者輸入時的實時驗證和提交請求。

表單的資料驗證,其中變化的部分只是不同的正則表示式和不同的input物件。

所以我們需要將變化的操作暴露給程式設計師,將不變的部分固定到類中。

我們可以通過給input標籤上打上自定義屬性,來繫結我們的不同的驗證正則表示式。

Form類

class Form{
    form
    //表示每個input是否合法
    state = []

    verifyList = {
        digit: (val)=>{
            return{
                msg:'非合法數字',
                reg:/\d+/
            }
        },
        phone:(val)=>{ 
            return{
                msg:'非合法電話',
                reg:/^1(3|4|5|6|7|8|9)\d{9}$/
            }
        }
    }
    constructor(id){
        this.form = document.querySelector(`#${id}`)
    }

    //初始化表單,給所有input繫結驗證事件
    init(){
        for (const key in this.form.elements) {
            //遍歷input
           if(parseInt(key)>=0&&this.form[key].tagName=='INPUT'){
               //為input繫結事件
                this.form[key].onblur = ()=>{
                    this.verify(this.form[key],key)
                }
                this.state[key] = false
           }
        }
    }
   
    //繫結提交事件 fn為使用者設定的回撥函式
    bindSubmit(fn){
        this.form.onsubmit = ()=>{
            let index = this.state.indexOf(false)
            if(index>=0){
                alert('提交失敗');
            }
            else{
                fn(this.form)
                alert('提交成功!');
            }
            return false;
        }
    }


    //驗證
    verify(obj,key){
        let value = obj.value;
        let rule = obj.getAttribute('verify')
        let rs = rule.split('|');
        //校驗每一條規則
        rs.forEach(rule => {
            //拿到驗證規則 和 提示資訊
            let x = this.verifyList[rule](value)
            let reg = RegExp(x.reg)
            //開始驗證 value 是否符合正則
            let msgSpan = document.querySelector(`#${obj.name}Error`)
            if(msgSpan){
                if( !(reg.test(value)) ){
                    msgSpan.innerHTML = x.msg
                    this.state[key] = false
                }
                else{
                    msgSpan.innerHTML = ""
                    this.state[key] = true
                }
            }
        });
    }

    addVerify([...obj]){
        obj.forEach(v=>{
            this.verifyList[v.name] = v.verify
        })
    }
    
}

  

index.html頁面中 佈局部分:

<style>
    form{
        display: flex;
        flex-direction: column;
    }
</style>
<body>
    <form action="#" id="ff">
        <div>
            <input type="text" name="username" value="" verify='username'>
            <span id="usernameError"></span>
        </div>
        <div>
            <input type="password" name="pwd" value="" verify='password'>
            <span id="pwdError"></span>
        </div>
        <div>
            <button type="submit">提交 </button>
        </div>

    </form>
</body>

  index.html 中繫結表單部分:

<script>
   
    let f = new Form('ff')
 
    f.addVerify([
        {
            name:'username',
            verify:()=>{
                return{
                    msg:'使用者名稱為4到16位(字母,數字,下劃線,減號)',
                    reg:/^[a-zA-Z0-9_-]{4,16}$/
                }
            }
        },
        {
            name:'password',
            verify:()=>{
                return{
                    msg:'最少6位,包括至少1個大寫字母,1個小寫字母,1個數字,1個特殊字元',
                    reg: /^.*(?=.{6,})(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*?\.]).*$/
                }
            }
        }
    ])

    //繫結提交事件
    f.bindSubmit((data)=>{
        console.log(data['username'].value);
    })
    //初始化
    f.init();
  

</script>