天天看點

js 政策模式 實作表單驗證政策模式

政策模式

簡單點說就是:實作目标的方式有很多種,你可以根據自己身情況選一個方法來實作目标.

是以至少有2個對象 .  一個是政策類,一個是環境類(上下文). 然後自己就可以根據上下文選擇不同的政策來執行方案.

政策模式的優點:

  1. 政策模式利用組合、委托和多态等技術和思想,可以有效地避免多重條件選擇語句

  2. 政策模式提供了對開放-封閉原則的完美支援,将算法封裝在獨立的 政策類 中,使得它們易于切換,易于了解,易于擴充.

 // html

<!DOCTYPE html>

<head>
    <meta charset="utf8">
    <title>政策模式實作表單驗證</title>
    <link rel="stylesheet" type="text/css" href="style.css" target="_blank" rel="external nofollow" >
    <script src="rule.js"></script>
    <script src="validator.js"></script>
</head>

<body>
    <form action="#" method="GET" id="form">
        <div class="field">
            <label>使用者名</label>
            <input type="text" name="name">
        </div>
        <div class="field">
            <label>聯系電話</label>
            <input type="text" name="mobile">
        </div>
        <div class="field">
            <label>郵箱</label>
            <input type="text" name="email">
        </div>
        <button class="submit" type="submit">送出</button>
    </form>
    <script>
        let dom = document.getElementById("form");

        let formValid = new FormValid(dom);

        formValid.add({
            field: "name",
            rule: new RequiredRule(),
            errormsg: "字段必填"
        })

        formValid.add({
            field: "name",
            rule: new LengthRule(10),
            errormsg: "限定長度為10個字元"
        })

        formValid.add({
            field: "mobile",
            rule: new MobileRule(),
            errormsg: "手機号碼錯誤"
        })

        formValid.add({
            field: "email",
            rule: new EmailRule(),
            errormsg: "郵箱格式錯誤"
        })

        dom.onsubmit = function (event) {
            let result = formValid.isValid();
            if (result !== true) {
                alert(result);
                return false;
            }
            alert("送出成功");
        }

    </script>
</body>

</html>
           

// css

#form{
    margin: 50px auto;
    width: 500px;
}

input {
    width: 350px;
    height: 24px;
    padding: 0 4px;
    float: left;
}

.field{
    margin-top: 10px;
    overflow: hidden;
}
label {
    float: left;
    text-align: right;
    width: 100px;
    overflow: hidden;
    padding-right: 5px;
}
.submit{
    margin-top: 20px;
    margin-left:104px;
}
           

 // 政策類

/**
 * 必填
 */
class RequiredRule {

    /**
     * 驗證
     * @param {string} value 值
     * @param {string} errormsg 錯誤資訊
     * @param {any} attach 附加參數
     * @returns {string|bool} 
     */
    test(value, errormsg, attach) {
        return /^(:?\s*)$/.test(value) ? errormsg : true;
    }
}

/**
 * 範圍
 */
class RangeRule {

    /**
     * 構造函數
     * @param {array} range 
     */
    constructor(range) {
        this.range = range;
    }

    /**
     * 驗證
     * @param {string} value 值
     * @param {string} errormsg 錯誤資訊
     * @returns {string|bool} 
     */
    test(value, errormsg) {
        value = Number.parseFloat(value);
        if (this.range[0] <= value && this.range[1] > value) {
            return true;
        }
        return errormsg;
    }
}

/**
 * 有效數值驗證
 */
class NumberRule {
    /**
     * 驗證
     * @param {string} value 值
     * @param {string} errormsg 錯誤資訊
     * @returns {string|bool} 
     */
    test(value, errormsg) {
        return /^(?:\d+)$/.test(value) || errormsg;
    }
}

/**
 * 郵箱驗證
 * 格式:登入名@主機名.域名
 */
class EmailRule {

    constructor() {
        this.rule = new RegExp(/(?:\w+)@(?:\w+)\.(?:\w+)/);
    }

    /**
     * 驗證
     * @param {string} value 值
     * @param {string} errormsg 錯誤資訊
     * @returns {string|bool} 
     */
    test(value, errormsg) {
        return this.rule.test(value) || errormsg;
    }
}

/**
 * 手機号驗證
 */
class MobileRule {
    constructor() {
        this.rule = new RegExp(/^1\d{10}$/);
    }

    /**
     * 驗證
     * @param {string} value 值
     * @param {string} errormsg 錯誤資訊
     * @returns {string|bool} 
     */
    test(value, errormsg) {
        return this.rule.test(value) || errormsg;
    }
}

class LengthRule {
    constructor(maxlength) {
        this.maxlength = maxlength;
    }

    /**
     * 驗證
     * @param {string} value 值
     * @param {string} errormsg 錯誤資訊
     * @returns {string|bool} 
     */
    test(value, errormsg) {
        return value.length > this.maxlength ? errormsg : true;
    }
}
           

// 環境類

class FormValid {

    /**
     * 構造函數
     * @param {HTMLFormElement} form 元素節點
     */
    constructor(form) {
        this.form = form;
        this.rules = [];
    }

    /**
     * 添加驗證規則
     * @param {object} option
     * @param {string} option.field  字段名
     * @param {object} option.rule  規則
     * @param {string} option.errormsg  錯誤資訊
     */
    add({ field, rule, errormsg }) {
        if (typeof rule.test == "function" && this.form[field]) {
            this.rules.push(() => {
                return rule.test(this.form[field].value, errormsg);
            });
        }
    }

    isValid() {
        let result = [];
        for (let i = 0; i < this.rules.length; i++) {
            let r = this.rules[i]();
            if (r !== true) result.push(r);
        }
        return result.length > 0 ? result : true;
    }
}
           

源碼:https://pan.baidu.com/s/17_oBg1dqmbxAdG_AW3sWgg

樣本:http://js.zhuamimi.cn/%E8%A1%A8%E5%8D%95%E9%AA%8C%E8%AF%81/

轉載于:https://www.cnblogs.com/whnba/p/10301407.html