Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述
我们在开发中对于表单的提交里面的参数验证是家常便饭了,很多ui框架对这个问题也进行了封装,你可以尝试手写出来吗?要求在表单中校验出name,age为必填项,age必须填写数字,tel与email需要符合手机和邮箱格式。
<form id="form">
<div><label>name:</label><input name="name" /></div>
<div><label>age:</label><input name="age" /></div>
<div><label>tel:</label><input name="tel" /></div>
<div><label>email:</label><input name="email" /></div>
<button id="btn" type="submit">submit</button>
</form>
<script type="module" src="./app.js"></script>
考察点
- 如何阻止form表单的提交
- 是否能手写一些简单的正则表达式
- 是否有程序设计的思维,如何避免重复判断
解题思路
-
e.preventdefault()方法可以阻止元素发生默认的行为,自然可以阻止表单提交。
document.getElementById("form").addEventListener("submit", e => { e.preventDefault() }) -
正则表达式,属于基本功,但能写一些简单的验证基本已经满足团队开发需要了。
let rules = { name: [{ required: true, msg: "名字不得为空" }], age: [ { required: true, msg: "年纪不得为空" }, { reg: /(^[1-9]\d*$)/, msg: "请输入正确的年纪" } ], tel: [ { reg: /^1\d{10}$/, msg: "请输入正确的电话号码" } ], email: [ { reg: /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/, msg: "请输入正确的邮箱地址" } ] } -
对于考察是否有程序设计思维,如何避免重复判断,所以你肯定不能直接去那正则去反复用if-else去判断提示,而是用更优雅的设计模式来完成。当然实现的方法非常多,可以是传统策略模式,也可以做对象配置判断,用是for...in 与 hasOwnProperty做过滤判断来完成。这里就用后者来实现,而且前者在很多程序设计书中都有案例,这里就不做赘述了。
function checkFormRules(rules, form) { for (const key in rules) { if (rules.hasOwnProperty(key) && form.hasOwnProperty(key)) { let item = rules[key], value = form[key]; for (let i = 0, len = item.length; i < len; i++) { const { reg, msg, required } = item[i]; if (required && !value) return msg if (reg && (!reg.test(value))) return msg; } } } }这里我们过滤出来要校验的字段,然后一一的进行判断,虽然扩展性不如传统策略模式也没有他优雅,但也可以用最快速度满足题目要求,核心代码极少,面试手写耗时短,如何完善的话,无限使用策略模式完成,增强其扩展性。
实现
刚才在分析的时候已经写好了大半,现在只需要使用他就可以完成了题目了。
; (function () { let form = document.getElementById("form") form.addEventListener("submit", e => { e.preventDefault() let values = { name: "", age: "", tel: "", email: "" } for (const key in values) { if (values.hasOwnProperty(key)) { values[key] = form[key].value } } let msg = checkFormRules(rules, values) if (msg) { return alert(msg) } alert("提交成功") }) })();