--- tags: Example, disqus: hackmd --- # 正規表達式練習 ## 程式碼 ### HTML ```htmlmixed= <html> <head> <title>week1 HTML Form 表單驗證</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="index.css"> </head> <body> <div class="page-body"> <h2>正規表達式-表單驗證練習</h2> <form id="myForm" class="myForm" onsubmit="return false"> <label for="account">帳號:</label> <input type="text" id="account" class="account field" value=""> <span class="rule">規則: 4~15 碼英文大小寫及數字</span><br> <label for="password">密碼:</label> <input type="password" id="password" class="password field" value=""> <span class="rule">規則: 6-12 大小寫英文及數字(密碼中至少要包含一個英文大寫)</span><br> <label for="confirmPassword">確認密碼:</label> <input type="password" id="confirmPassword" class="confirmPassword field" value=""> <span class="rule">規則: 欄位必須與密碼相符</span><br> <label for="nickname">暱稱:</label> <input type="text" id="nickname" class="nickname field" value=""> <span class="rule">規則: 名稱中不可包含 {}[]"", 並且僅能輸入 2-10字元</span><br> <label for="realname">真實姓名:</label> <input type="text" id="realname" class="realname field" value=""> <span class="rule">規則: 不可輸入數字、空白及特殊符號 最多6字</span><br> <label for="enName">英文姓名:</label> <input type="text" id="enName" class="enName field" value=""> <span class="rule">規則: 可輸入英文大小寫、空白、單引號及底線</span><br> <label for="birthday">生日:</label> <input type="text" id="birthday" class="birthday field" value=""> <span class="rule">規則: dd/mm/yyyy</span><br> <label for="country">國家:</label> <input type="text" id="country" class="country field" value=""> <span class="rule">規則: 不能輸入特殊符號,但可以輸入空格</span><br> <label for="identity">證件:</label> <input type="text" id="identity" class="identity field" value=""> <span class="rule">規則: 可輸入英文大小寫數字也可以輸入底線</span><br> <label for="cellphone">手機:</label> <input type="tel" id="cellphone" class="cellphone field" value=""> <span class="rule">規則: 僅能數字但可以包含+開頭</span><br> <label for="function1">function1:</label> <span id="function1Notice"></span> <input type="tel" id="function1" class="function1 field" value=""> <br><br> <label for="function2">function2:</label> <span id="function2Notice"></span> <input type="tel" id="function2" class="function2 field" value=""> <span class="rule">規則: 僅能整數或包含小數點</span><br> <br> <input id="submitButton" type="submit" value="送出"> <input id="resetButton" type="reset" value="清除"> </form> </div> </body> <script src="index.js"></script> </html> ``` ### CSS ```css= .page-body { white-space: nowrap; text-align: center; } .myForm { display: inline-block; margin: 0 auto; border-radius: 15px; padding: 15px; background: bisque; width: 700px; box-sizing: border-box; vertical-align: middle; } .myForm label { display: inline-block; width: 70px; } input:focus{ outline: none; } input { border: solid 1px #CCC; } .field.error { border-color: red; } .rule { display: block; color: red; font-size: 14px; opacity: 0; } .rule.show { opacity: 1; } ``` ### JS ```javascript= /* 立即函示 + 閉包 */ (function() { function handleOnload(){ var myForm = document.getElementById('myForm'); var inputField = document.getElementsByClassName('field'); var password = document.getElementById('password'); var confirmPassword = document.getElementById('confirmPassword'); var function1 = document.getElementById('function1'); var function2 = document.getElementById('function2'); var function1Notice = document.getElementById('function1Notice'); var function2Notice = document.getElementById('function2Notice'); var submitButton = document.getElementById('submitButton'); var resetButton = document.getElementById('resetButton'); var myObj = { checkConfirmPassword: function() { var passwordValue = password.value; var confirmPasswordValue = confirmPassword.value; return passwordValue === confirmPasswordValue; }, checkHandler: function(name, pattern) { var targetInput = document.getElementById(name); var targetInputCheck = pattern.test(targetInput.value); return targetInputCheck; }, verifyList: function(id) { var result = null; switch (id) { case 'account': result = this.checkHandler('account', /^([a-zA-Z0-9]){4,15}$/g); break; case 'password': result = this.checkHandler('password', /^(?=.*[A-Z])[a-zA-Z0-9]{6,12}$/g); break; case 'confirmPassword': result = this.checkConfirmPassword(); break; case 'nickname': result = this.checkHandler('nickname', /^[^{}\]\["]{2,10}$/g); break; case 'realname': result = this.checkHandler('realname', /^[a-zA-Z\u4e00-\u9fa5]{1,6}$/g); break; case 'enName': result = this.checkHandler('enName', /^[a-zA-Z _']+$/g); break; case 'birthday': result = this.checkHandler('birthday', /^([0][1-9]|[1-2][0-9]|[3][0-1])[\/]([0-1][1-9]|[01][0-2])[\/](19|20)([\d]{2})$/g); break; case 'country': result = this.checkHandler('country', /^([^\W]|[ \u4e00-\u9fa5])+$/g); break; case 'identity': result = this.checkHandler('identity', /^[\w]+$/g); break; case 'cellphone': result = this.checkHandler('cellphone', /^([+]?)([\d]+)$/g); break; case 'function2': result = this.checkHandler('function2', /^([\d]+)(([\.][\d]+)?)$/g); break; default: result = true; } return result; }, handleVerify: function(id, type) { var result = null; if (type === 'submit') { result = document.getElementById(id).value && this.verifyList(id); if (!result) { document.getElementById(id).classList.add('error'); document.getElementById(id).nextElementSibling.classList.add('show'); } if (id === 'function1' && result) { this.handleRemoveSpace(); } if (id === 'function2' && result) { this.handleDecimalPoint(); } return result; } if (type === 'keyup' || type === 'blur') { result = document.getElementById(id).value && this.verifyList(id); if (id === 'password' && confirmPassword.value) { result = result && this.checkConfirmPassword(); if (result) { confirmPassword.classList.remove('error'); confirmPassword.nextElementSibling.classList.remove('show'); } else { confirmPassword.classList.add('error'); confirmPassword.nextElementSibling.classList.add('show'); } } else { if (result) { document.getElementById(id).classList.remove('error'); document.getElementById(id).nextElementSibling.classList.remove('show'); } else { document.getElementById(id).classList.add('error'); document.getElementById(id).nextElementSibling.classList.add('show'); } } } }, handleSubmit: function() { submitButton.addEventListener('click', function() { let succeedVerify = 0; for (let index = 0; index < inputField.length; index++) { var id = inputField[index].getAttribute('id'); var state = myObj.handleVerify(id, 'submit'); if (state) { succeedVerify = succeedVerify + 1; } } if (succeedVerify === inputField.length) { alert('表單送出成功'); myForm.submit(); } else { document.getElementsByClassName('error')[0].focus(); } }); }, handleKeyup: function() { for (let index = 0; index < inputField.length; index++) { inputField[index].addEventListener('keyup', function() { myObj.handleVerify(inputField[index].getAttribute('id'), 'keyup'); }, true); } }, handleUnfocus: function() { for (let index = 0; index < inputField.length; index++) { inputField[index].addEventListener('blur', function() { myObj.handleVerify(inputField[index].getAttribute('id'), 'blur'); }, true); } }, handleReset: function() { resetButton.addEventListener('click', function() { for (let index = 0; index < inputField.length; index++) { inputField[index].classList.remove('error'); inputField[index].nextElementSibling.classList.remove('show'); } function1Notice.innerHTML = ''; function2Notice.innerHTML = ''; }); }, handleRemoveSpace: function() { function1Notice.innerHTML = function1.value.split(/([\S][\w\W\s]+[\S])/g)[1]; }, handleDecimalPoint: function() { function2Notice.innerHTML = function2.value.replace(/([0-9]+)[\.]?([\d]+)?/, '『整數:$1, 小數點:0.$2』'); }, handleExecute: function() { this.handleSubmit(); this.handleKeyup(); this.handleUnfocus(); this.handleReset(); } } return myObj; }; var executeOnload = handleOnload(); executeOnload.handleExecute(); })(); /* 立即函示 + 閉包 */ ```