国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

探索兩種優(yōu)雅的表單驗(yàn)證——策略設(shè)計(jì)模式和ES6的Proxy代理模式

light / 2086人閱讀

原文收錄在我的 GitHub博客 (https://github.com/jawil/blog) ,喜歡的可以關(guān)注最新動(dòng)態(tài),大家一起多交流學(xué)習(xí),共同進(jìn)步,以學(xué)習(xí)者的身份寫博客,記錄點(diǎn)滴。

在一個(gè)Web項(xiàng)目中,注冊(cè),登錄,修改用戶信息,下訂單等功能的實(shí)現(xiàn)都離不開(kāi)提交表單。這篇文章就闡述了如何編寫相對(duì)看著舒服的表單驗(yàn)證代碼。

假設(shè)我們正在編寫一個(gè)注冊(cè)的頁(yè)面,在點(diǎn)擊注冊(cè)按鈕之前,有如下幾條校驗(yàn)邏輯。

所有選項(xiàng)不能為空

用戶名長(zhǎng)度不能少于6位

密碼長(zhǎng)度不能少于6位

手機(jī)號(hào)碼必須符合格式

郵箱地址必須符合格式

注:為簡(jiǎn)單起見(jiàn),以下例子以傳統(tǒng)的瀏覽器表單驗(yàn)證,Ajax異步請(qǐng)求不做探討,瀏覽器端驗(yàn)證原理圖:

簡(jiǎn)要說(shuō)明:

這里我們前端只做瀏覽器端的校驗(yàn)。很多工具可以在表單檢驗(yàn)過(guò)后、瀏覽器發(fā)送請(qǐng)求前截取表單數(shù)據(jù),攻擊者可以修改請(qǐng)求中的數(shù)據(jù),從而繞過(guò) JavaScript,將惡意數(shù)據(jù)注入服務(wù)器,這樣會(huì)增加XSS(全稱 Cross Site Scripting)攻擊的機(jī)率。對(duì)于一般的網(wǎng)站,都不贊成采用瀏覽器端的表單驗(yàn)證方法。瀏覽器端和服務(wù)器端雙重驗(yàn)證方法在瀏覽器端驗(yàn)證方法基礎(chǔ)上增加服務(wù)器端的驗(yàn)證,其原理如圖所示,該方法增加服務(wù)器端的驗(yàn)證,彌補(bǔ)了傳統(tǒng)瀏覽器端驗(yàn)證的缺點(diǎn)。若表單輸入不符合要求,瀏覽器端的 Javascript 驗(yàn)證能很快地給出響應(yīng),而服務(wù)器端的驗(yàn)證則可以防止惡意用戶繞過(guò) Javascript 驗(yàn)證,保證最終數(shù)據(jù)的準(zhǔn)確性。

HTML代碼:




    
    
    探索幾種表單驗(yàn)證最佳實(shí)踐方式


    

JavaScript代碼:

  let registerForm = document.querySelector("#registerForm")
  registerForm.addEventListener("submit", function() {
      if (registerForm.userName.value === "") {
          alert("用戶名不能為空!")
          return false
      }
      if (registerForm.userName.length < 6) {
          alert("用戶名長(zhǎng)度不能少于6位!")
          return false
      }
      if (registerForm.passWord.value === "") {
          alert("密碼不能為空!")
          return false
      }
      if (registerForm.passWord.value.length < 6) {
          alert("密碼長(zhǎng)度不能少于6位!")
          return false
      }
      if (registerForm.phoneNumber.value === "") {
          alert("手機(jī)號(hào)碼不能為空!")
          return false
      }
      if (!/^1(3|5|7|8|9)[0-9]{9}$/.test(registerForm.phoneNumber.value)) {
          alert("手機(jī)號(hào)碼格式不正確!")
          return false
      }
      if (registerForm.emailAddress.value === "") {
          alert("郵箱地址不能為空!")
          return false
      }
      if (!/^w+([+-.]w+)*@w+([-.]w+)*.w+([-.]w+)*
      $/.test(registerForm.emailAddress.value)) {
          alert("郵箱地址格式不正確!")
          return false
      }
  }, false)
1、問(wèn)題

這樣編寫代碼,的確能夠完成業(yè)務(wù)的需求,能夠完成表單的驗(yàn)證,但是存在很多問(wèn)題,比如:

registerForm.addEventListener綁定的函數(shù)比較龐大,包含了很多的if-else語(yǔ)句,看著都惡心,這些語(yǔ)句需要覆蓋所有的校驗(yàn)規(guī)則。

registerForm.addEventListener綁定的函數(shù)缺乏彈性,如果增加了一種新的校驗(yàn)規(guī)則,或者想要把密碼的長(zhǎng)度校驗(yàn)從6改成8,我們都必須深入registerForm.addEventListener綁定的函數(shù)的內(nèi)部實(shí)現(xiàn),這是違反了開(kāi)放-封閉原則的。

算法的復(fù)用性差,如果程序中增加了另一個(gè)表單,這個(gè)表單也需要進(jìn)行一些類似的校驗(yàn),那我們很可能將這些校驗(yàn)邏輯復(fù)制得漫天遍野。

所謂辦法總比問(wèn)題多,辦法是有的,比如馬上要講解的使用 策略模式 使表單驗(yàn)證更優(yōu)雅更完美,我相信很多人很抵觸設(shè)計(jì)模式,一聽(tīng)設(shè)計(jì)模式就覺(jué)得很遙遠(yuǎn),覺(jué)得自己在工作中很少用到設(shè)計(jì)模式,那么你就錯(cuò)了,特別是JavaScript這種靈活的語(yǔ)言,有的時(shí)候你已經(jīng)在你的代碼中使用了設(shè)計(jì)模式,只是你不知道而已。更多關(guān)于設(shè)計(jì)模式的東西,以后會(huì)陸續(xù)寫博客描述,這里只希望大家拋棄設(shè)計(jì)模式神秘的感覺(jué),通俗的講,它無(wú)非就是完成一件事情通用的辦法而已。

2、思路

回到正題,假如我們不想使用過(guò)多的 if - else 語(yǔ)句,那么我們心中比較理想的代碼編寫方式是什么呢?我們能不能像編寫配置一樣的去做表單驗(yàn)證呢?再來(lái)一個(gè)”一鍵驗(yàn)證“的功能,是不是很爽?答案是肯定的,所以我們心中理想的編寫代碼的方式如下:

// 獲取表單form元素
let registerForm = document.querySelector("#registerForm")

// 創(chuàng)建表單校驗(yàn)實(shí)例
let validator = new Validator();
// 編寫校驗(yàn)配置
validator.add(registerForm.userName, "isNonEmpty", "用戶名不能為空")
validator.add(registerForm.userName, "minLength:6", "用戶名長(zhǎng)度不能小于6")

// 開(kāi)始校驗(yàn),并接收錯(cuò)誤信息
let errorMsg = validator.start()

// 如果有錯(cuò)誤信息輸出,說(shuō)明校驗(yàn)未通過(guò)
if(errorMsg){
    alert(errorMsg)
    return false//阻止表單提交
}

怎么樣?感受感受,是不是看上去優(yōu)雅多了?好了,有了這些思路,我們就可以向目標(biāo)邁進(jìn)了,下一步就要了解了解什么事策略模式了。

3、策略模式

策略模式,單純的看它的名字”策略“,指的是做事情的方法,比如我們想到某個(gè)地方旅游,你可以有幾種策略供選擇:
1、飛機(jī),嗖嗖嗖直接就到了,節(jié)省時(shí)間。
2、火車,可以選擇高鐵出行,專為飛機(jī)恐懼癥者提供。
3、徒步,不失為一個(gè)鍛煉身體的選擇。
4、other method……

在程序設(shè)計(jì)中,我們也經(jīng)常遇到類似的情況,要實(shí)現(xiàn)一種方案有多種方案可以選擇,比如,一個(gè)壓縮文件的程序,即可選擇zip算法,也可以選擇gzip算法。

所以,做一件事你會(huì)有很多方法,也就是所謂的策略,而我們今天要講的策略模式也就是這個(gè)意思,它的核心思想是,將做什么和誰(shuí)去做相分離。所以,一個(gè)完整的策略模式要有兩個(gè)類,一個(gè)是策略類,一個(gè)是環(huán)境類(主要類),環(huán)境類接收請(qǐng)求,但不處理請(qǐng)求,它會(huì)把請(qǐng)求委托給策略類,讓策略類去處理,而策略類的擴(kuò)展是很容易的,這樣,使得我們的代碼易于擴(kuò)展。
在表單驗(yàn)證的例子中,各種驗(yàn)證的方法組成了策略類,比如:判斷是否為空的方法(如:isNonEmpty),判斷最小長(zhǎng)度的方法(如:minLength),判斷是否為手機(jī)號(hào)的方法(isMoblie)等等,他們組成了策略類,供給環(huán)境類去委托請(qǐng)求。下面,我們就來(lái)實(shí)戰(zhàn)一下。

4、用策略模式重構(gòu)表單校驗(yàn)

策略模式的組成

抽象策略角色:策略類,通常由一個(gè)接口或者抽象類實(shí)現(xiàn)。
具體策略角色:包裝了相關(guān)的算法和行為。
環(huán)境角色:持有一個(gè)策略類的引用,最終給客戶端用的。

4.1具體策略角色——編寫策略類

策略類很簡(jiǎn)單,它是由一組驗(yàn)證方法組成的對(duì)象,即策略對(duì)象,重構(gòu)表單校驗(yàn)的代碼,很顯然第一步我們要把這些校驗(yàn)邏輯都封裝成策略對(duì)象:

/*策略對(duì)象*/
const strategies = {
        isNonEmpty(value, errorMsg) {
            return value === "" ?
                errorMsg : void 0
        },
        minLength(value, length, errorMsg) {
            return value.length < length ?
                errorMsg : void 0
        },
        isMoblie(value, errorMsg) {
            return !/^1(3|5|7|8|9)[0-9]{9}$/.test(value) ?
                errorMsg : void 0
        },
        isEmail(value, errorMsg) {
            return !/^w+([+-.]w+)*@w+([-.]w+)*.w+([-.]w+)*$/.test(value) ?
                errorMsg : void 0
        }
    }
4.2抽象策略角色——編寫Validator類

根據(jù)我們的思考,我們使用add方法添加驗(yàn)證配置,如下:

validator.add(registerForm.userName, "isNonEmpty", "用戶名不能為空")
validator.add(registerForm.userName, "minLength:6", "用戶名長(zhǎng)度不能小于6")

add方法接受三個(gè)參數(shù),第一個(gè)參數(shù)是表單字段,第二個(gè)參數(shù)是策略對(duì)象中策略方法的名字,第三個(gè)參數(shù)是驗(yàn)證未通過(guò)的錯(cuò)誤信息。

然后使用 start 方法開(kāi)始驗(yàn)證,若驗(yàn)證未通過(guò),返回驗(yàn)證錯(cuò)誤信息,如下:

let errorMsg = validator.start()

另外,再解釋一下下面這句代碼:

add方法第一個(gè)參數(shù)我們說(shuō)過(guò)了,是要驗(yàn)證的表單元素,第二個(gè)參數(shù)是一個(gè)字符串,使用 冒號(hào)(:) 分割,前面是策略方法名稱,后面是傳給這個(gè)方法的參數(shù),第三個(gè)參數(shù)仍然是錯(cuò)誤信息。

但是這種參數(shù)配置還是有問(wèn)題,我們的要求是多種校驗(yàn)規(guī)則,比如用戶名既不能為空,又要滿足用戶名長(zhǎng)度不小于6,并不是單一的,上面的為什么要寫兩次,這種看著就不舒服,這時(shí)候我就需要對(duì)配置參數(shù)做一點(diǎn)小小的改動(dòng),我們用數(shù)組來(lái)傳遞多個(gè)校驗(yàn)規(guī)則:

validator.add(registerForm.userName, [{
        strategy: "isNonEmpty",
        errorMsg: "用戶名不能為空!"
    }, {
        strategy: "minLength:6",
        errorMsg: "用戶名長(zhǎng)度不能小于6位!"
    }])

最后是Validator類的實(shí)現(xiàn):

/*Validator類*/
class Validator {
    constructor() {
        this.cache = [] //保存校驗(yàn)規(guī)則
    }
    add(dom, rules) {
        for (let rule of rules) {
            let strategyAry = rule.strategy.split(":") //例如["minLength",6]
            let errorMsg = rule.errorMsg //"用戶名不能為空"
            this.cache.push(() => {
                let strategy = strategyAry.shift() //用戶挑選的strategy
                strategyAry.unshift(dom.value) //把input的value添加進(jìn)參數(shù)列表
                strategyAry.push(errorMsg) //把errorMsg添加進(jìn)參數(shù)列表,[dom.value,6,errorMsg]
                return strategies[strategy].apply(dom, strategyAry)
            })
        }
    }
    start() {
        for (let validatorFunc of this.cache) {
            let errorMsg = validatorFunc()//開(kāi)始校驗(yàn),并取得校驗(yàn)后的返回信息
            if (errorMsg) {//r如果有確切返回值,說(shuō)明校驗(yàn)沒(méi)有通過(guò)
                return errorMsg
            }
        }
    }
}
4.3環(huán)境角色——客戶端調(diào)用代碼

使用策略模式重構(gòu)代碼以后,我們僅僅通過(guò)‘配置’的方式就可以完成一個(gè)表單的校驗(yàn),這些校驗(yàn)規(guī)則也可以復(fù)用在程序的任何地方,還能作為插件的形式,方便地被移植到其他項(xiàng)目中。

/*客戶端調(diào)用代碼*/
let registerForm = document.querySelector("#registerForm")
const validatorFunc = () => {
    let validator = new Validator()

    validator.add(registerForm.userName, [{
        strategy: "isNonEmpty",
        errorMsg: "用戶名不能為空!"
    }, {
        strategy: "minLength:6",
        errorMsg: "用戶名長(zhǎng)度不能小于6位!"
    }])

    validator.add(registerForm.passWord, [{
        strategy: "isNonEmpty",
        errorMsg: "密碼不能為空!"
    }, {
        strategy: "minLength:",
        errorMsg: "密碼長(zhǎng)度不能小于6位!"
    }])

    validator.add(registerForm.phoneNumber, [{
        strategy: "isNonEmpty",
        errorMsg: "手機(jī)號(hào)碼不能為空!"
    }, {
        strategy: "isMoblie",
        errorMsg: "手機(jī)號(hào)碼格式不正確!"
    }])

    validator.add(registerForm.emailAddress, [{
        strategy: "isNonEmpty",
        errorMsg: "郵箱地址不能為空!"
    }, {
        strategy: "isEmail",
        errorMsg: "郵箱地址格式不正確!"
    }])
    let errorMsg = validator.start()
    return errorMsg
}

registerForm.addEventListener("submit", function() {
    let errorMsg = validatorFunc()
    if (errorMsg) {
        alert(errorMsg)
        return false
    }
}, false)

在修改某個(gè)校驗(yàn)規(guī)則的時(shí)候,只需要編寫或者改寫少量的代碼。比如我們想要將用戶名輸入框的校驗(yàn)規(guī)則改成用戶名不能少于4個(gè)字符。可以看到,這時(shí)候的修改是毫不費(fèi)力的。代碼如下:

 validator.add(registerForm.userName, [{
        strategy: "isNonEmpty",
        errorMsg: "用戶名不能為空!"
    }, {
        strategy: "minLength:4",
        errorMsg: "用戶名長(zhǎng)度不能小于4位!"
    }])
4.4策略模式的優(yōu)缺點(diǎn)

策略模式利用組合、委托和多態(tài)等技術(shù)思想,可以有效的避免多種條件選擇語(yǔ)句;

策略模式提供了對(duì)開(kāi)放-封閉原則的完美支持,將算法封裝在獨(dú)立的strategy中,使得它易于切換,易于理解,易于拓展;

策略模式中的算法也可以復(fù)用在系統(tǒng)的其它地方,從而避免了許多重復(fù)的復(fù)制黏貼的工作;

在策略模式利用組合和委托來(lái)讓Context擁有執(zhí)行算法的能力,這也是繼承一種更輕便的替代方案。

當(dāng)然,策略模式也有一些缺點(diǎn),但掌握了策略模式,這些缺點(diǎn)并不嚴(yán)重。

編寫難度加大,代碼量變多了,這是最直觀的一個(gè)缺點(diǎn),也算不上缺點(diǎn),畢竟不能完全以代碼多少來(lái)衡量?jī)?yōu)劣。

首先,使用策略模式會(huì)在程序中增加許多策略類或者策略對(duì)象,但實(shí)際上這比把它們負(fù)責(zé)的邏輯堆砌在Context中要好。

其次,要使用策略模式,必須了解所有的strategy,必須了解各個(gè)strategy之間的不同點(diǎn),這樣才能選擇一個(gè)合適的strategy。比如,我們要選擇一種合適的旅游出行路線,必須先了解選擇飛機(jī)、火車、自行車等方案的細(xì)節(jié)。此時(shí)strategy要向客戶暴露它的所有實(shí)現(xiàn),這是違反最少知識(shí)原則的。

4.5策略模式的意義

策略模式使開(kāi)發(fā)人員能夠開(kāi)發(fā)出由許多可替換的部分組成的軟件,并且各個(gè)部分之間是弱連接的關(guān)系。
弱連接的特性使軟件具有更強(qiáng)的可擴(kuò)展性,易于維護(hù);更重要的是,它大大提高了軟件的可重用性。

關(guān)于ES6d的Proxy對(duì)象

策略模式固然可行,但是包裝的有點(diǎn)多了,而且不便于書寫,代碼書寫量增加了不少,也就是有一定門檻,那有沒(méi)有更好的實(shí)現(xiàn)方式呢?我們能不能通過(guò)一層代理,在設(shè)置屬性時(shí)候就去攔截它呢?這就是今天要講到的ES6的Proxy對(duì)象。

1、概述

Proxy 用于修改某些操作的默認(rèn)行為,等同于在語(yǔ)言層面做出修改,所以屬于一種“元編程”(meta programming),即對(duì)編程語(yǔ)言進(jìn)行編程。

Proxy 可以理解成,在目標(biāo)對(duì)象之前架設(shè)一層“攔截”,外界對(duì)該對(duì)象的訪問(wèn),都必須先通過(guò)這層攔截,因此提供了一種機(jī)制,可以對(duì)外界的訪問(wèn)進(jìn)行過(guò)濾和改寫。Proxy 這個(gè)詞的原意是代理,用在這里表示由它來(lái)“代理”某些操作,可以譯為“代理器”。

let obj = new Proxy({}, {
  get (target, key, receiver) {
    console.log(`getting ${key}!`)
    return Reflect.get(target, key, receiver)
  },
  set (target, key, value, receiver) {
    console.log(`setting ${key}!`)
    return Reflect.set(target, key, value, receiver)
  }
})

上面代碼對(duì)一個(gè)空對(duì)象架設(shè)了一層攔截,重定義了屬性的讀取(get)和設(shè)置(set)行為。這里暫時(shí)先不解釋具體的語(yǔ)法,只看運(yùn)行結(jié)果。對(duì)設(shè)置了攔截行為的對(duì)象obj,去讀寫它的屬性,就會(huì)得到下面的結(jié)果。

obj.count = 1
//  setting count!
++obj.count
//  getting count!
//  setting count!
//  2

上面代碼說(shuō)明,Proxy 實(shí)際上重載(overload)了點(diǎn)運(yùn)算符,即用自己的定義覆蓋了語(yǔ)言的原始定義。

ES6 原生提供 Proxy 構(gòu)造函數(shù),用來(lái)生成 Proxy 實(shí)例。

let proxy = new Proxy(target, handler);

Proxy 對(duì)象的所有用法,都是上面這種形式,不同的只是handler參數(shù)的寫法。其中,new Proxy()表示生成一個(gè)Proxy實(shí)例,target參數(shù)表示所要攔截的目標(biāo)對(duì)象,handler參數(shù)也是一個(gè)對(duì)象,用來(lái)定制攔截行為。

下面是另一個(gè)攔截讀取屬性行為的例子。

var proxy = new Proxy({}, {
  get: function(target, property) {
    return 35;
  }
});

proxy.time // 35
proxy.name // 35
proxy.title // 35

上面代碼中,作為構(gòu)造函數(shù),Proxy接受兩個(gè)參數(shù)。第一個(gè)參數(shù)是所要代理的目標(biāo)對(duì)象(上例是一個(gè)空對(duì)象),即如果沒(méi)有Proxy的介入,操作原來(lái)要訪問(wèn)的就是這個(gè)對(duì)象;第二個(gè)參數(shù)是一個(gè)配置對(duì)象,對(duì)于每一個(gè)被代理的操作,需要提供一個(gè)對(duì)應(yīng)的處理函數(shù),該函數(shù)將攔截對(duì)應(yīng)的操作。比如,上面代碼中,配置對(duì)象有一個(gè)get方法,用來(lái)攔截對(duì)目標(biāo)對(duì)象屬性的訪問(wèn)請(qǐng)求。get方法的兩個(gè)參數(shù)分別是目標(biāo)對(duì)象和所要訪問(wèn)的屬性。可以看到,由于攔截函數(shù)總是返回35,所以訪問(wèn)任何屬性都得到35

注意,要使得Proxy起作用,必須針對(duì)Proxy實(shí)例(上例是proxy對(duì)象)進(jìn)行操作,而不是針對(duì)目標(biāo)對(duì)象(上例是空對(duì)象)進(jìn)行操作。

2、利用Proxy重構(gòu)表單驗(yàn)證

利用proxy攔截不符合要求的數(shù)據(jù)

function validator(target, validator, errorMsg) {
    return new Proxy(target, {
        _validator: validator,
        set(target, key, value, proxy) {
            let errMsg = errorMsg
            if (value == "") {
                alert(`${errMsg[key]}不能為空!`)
                return target[key] = false
            }
            let va = this._validator[key]
            if (!!va(value)) {
                return Reflect.set(target, key, value, proxy)
            } else {
                alert(`${errMsg[key]}格式不正確`)
                return target[key] = false
            }
        }
    })
}

負(fù)責(zé)校驗(yàn)的邏輯代碼

const validators = {
        name(value) {
            return value.length > 6
        },
        passwd(value) {
            return value.length > 6
        },
        moblie(value) {
            return /^1(3|5|7|8|9)[0-9]{9}$/.test(value)
        },
        email(value) {
            return /^w+([+-.]w+)*@w+([-.]w+)*.w+([-.]w+)*$/.test(value)
        }
    }

客戶端調(diào)用代碼

const errorMsg = { name: "用戶名", passwd: "密碼", moblie: "手機(jī)號(hào)碼", email: "郵箱地址" }
const vali = validator({}, validators, errorMsg)
let registerForm = document.querySelector("#registerForm")
registerForm.addEventListener("submit", function() {
        let validatorNext = function*() {
            yield vali.name = registerForm.userName.value
            yield vali.passwd = registerForm.passWord.value
            yield vali.moblie = registerForm.phoneNumber.value
            yield vali.email = registerForm.emailAddress.value
        }
        let validator = validatorNext()
        validator.next();
        !vali.name || validator.next(); //上一步的校驗(yàn)通過(guò)才執(zhí)行下一步
        !vali.passwd || validator.next();
        !vali.moblie || validator.next();
    }, false)

優(yōu)點(diǎn):條件和對(duì)象本身完全隔離開(kāi),后續(xù)代碼的維護(hù),代碼整潔度,以及代碼健壯性和復(fù)用性變得非常強(qiáng)。
缺點(diǎn):兼容性不好,有babel怕啥,粗糙版,很多細(xì)節(jié)其實(shí)還可以優(yōu)化,這里只提供一種思路。

參考文獻(xiàn)

JavaScript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐
ECMAScript 6 入門
策略模式在表單驗(yàn)證中的應(yīng)用

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/50781.html

相關(guān)文章

  • 探索兩種優(yōu)雅表單驗(yàn)證——策略設(shè)計(jì)模式ES6Proxy代理模式

    原文收錄在我的 GitHub博客 (https://github.com/jawil/blog) ,喜歡的可以關(guān)注最新動(dòng)態(tài),大家一起多交流學(xué)習(xí),共同進(jìn)步,以學(xué)習(xí)者的身份寫博客,記錄點(diǎn)滴。 在一個(gè)Web項(xiàng)目中,注冊(cè),登錄,修改用戶信息,下訂單等功能的實(shí)現(xiàn)都離不開(kāi)提交表單。這篇文章就闡述了如何編寫相對(duì)看著舒服的表單驗(yàn)證代碼。 假設(shè)我們正在編寫一個(gè)注冊(cè)的頁(yè)面,在點(diǎn)擊注冊(cè)按鈕之前,有如下幾條校驗(yàn)邏輯。 ...

    Bamboy 評(píng)論0 收藏0
  • JavaScript 設(shè)計(jì)模式(三):代理模式

    摘要:虛擬代理延遲執(zhí)行虛擬代理的目的,是將開(kāi)銷大的運(yùn)算延遲到需要時(shí)再執(zhí)行。 showImg(https://segmentfault.com/img/bVbuitm?w=800&h=600); 代理模式:為一個(gè)對(duì)象提供一個(gè)代用品或占位符,以便控制它的訪問(wèn)。 當(dāng)我們不方便直接訪問(wèn)某個(gè)對(duì)象時(shí),或不滿足需求時(shí),可考慮使用一個(gè)替身對(duì)象來(lái)控制該對(duì)象的訪問(wèn)。替身對(duì)象可對(duì)請(qǐng)求預(yù)先進(jìn)行處理,再?zèng)Q定是否轉(zhuǎn)交給...

    Keagan 評(píng)論0 收藏0
  • 前端資源收集整理

    摘要:工作原因,最近一年斷斷續(xù)續(xù)寫了一點(diǎn)前端代碼,收集整理了一些資料,和大家共享。 工作原因,最近一年斷斷續(xù)續(xù)寫了一點(diǎn)前端代碼,收集整理了一些資料,和大家共享。 Github版本:Front-End Resource Collection 前端相關(guān)資源匯總 學(xué)習(xí)指導(dǎo) 精華文章 Web前端的路該怎么走?:文章超長(zhǎng),但是干貨超級(jí)多,值得反復(fù)精讀! 聽(tīng)說(shuō)2017你想寫前端?:適合于已經(jīng)度過(guò)了小白階...

    awesome23 評(píng)論0 收藏0
  • 前端資源收集整理

    摘要:工作原因,最近一年斷斷續(xù)續(xù)寫了一點(diǎn)前端代碼,收集整理了一些資料,和大家共享。 工作原因,最近一年斷斷續(xù)續(xù)寫了一點(diǎn)前端代碼,收集整理了一些資料,和大家共享。 Github版本:Front-End Resource Collection 前端相關(guān)資源匯總 學(xué)習(xí)指導(dǎo) 精華文章 Web前端的路該怎么走?:文章超長(zhǎng),但是干貨超級(jí)多,值得反復(fù)精讀! 聽(tīng)說(shuō)2017你想寫前端?:適合于已經(jīng)度過(guò)了小白階...

    antyiwei 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<