要求
- 如图 以及 github代码地址
- 表单获得焦点时,下方显示表单填写规则
- 表单失去焦点时校验表单内容
- 校验结果正确时,表单边框显示绿色,并在下方显示验证通过的描述文字
- 校验结果错误时,表单边框显示红色,并在下方显示验证错误的描述文字
- 点击提交按钮时,对页面中所有输入进行校验,校验结果显示方式同上。若所有表单校验通过,弹窗显示“提交成功”,否则显示“提交失败”
思考
因为才学习了面向对象变成,就像第一次尝试一下一个完整的面向对象编程感觉,但是我的构思我感觉不是最好的,我没有用到继承,可能因为对象不够多,所以我只选择了一个
fomeObj
表单对象,来作为一个基类(也不知道这样说合不合适)。给
formObj.prototype
添加方法,其中style
和tip
方法都是从几个操作中再次抽取出来的方法。所以可能,如果要运用继承的话,formObj
父类,可以拥有style,tip
,然后剩下的几个验证再组合成一个子类,继承form
父类。
FormObj.prototype = {
constructor:FormObj,
// 改变input框样式和tips字体颜色
style : function(el,text,color){ },
// 绑定每一个tip对应的dom
tip : function (el,opt) { },
// 验证姓名
nameVali : function() { },
// 用来判断是否为空以及格式是否正确
passwordVali : function(sign) { },
// 验证是否密码一致
passwordCom : function(el) { },
// 验证邮箱输入,正确的格式xxxx@xxx.xxxx
emailVali : function() { },
// 验证手机,格式为11位数字
telVali : function() { }
}
-
然后整个流程,其实比较复杂,先说一下我的最初基本流程。
-
<p class="tips"></p>
在每一个.formGroup
里面都包含这样一个tips
类,最初显示为display
,然后在监听blur
事件的时候,通过tip()
并且绑定this
对象,使用switch语句
插入不同的提示语。 switch (opt) {
case 1 : tip = "必填,请输入4-16个字符";
break;
case 2 : tip = "必填,请输入6-10个字符 只能输入数字以及英文字母";
break;
case 3 : tip = "必填,请确认您的密码";
break;
case 4 : tip = "必填,按照正确的格式xxxx@xxx.xxxx";
break;
case 5 : tip = "必填,请填写11位手机号";
break;
default:
break;
}- 然后最后点击提交的时候需要判断是否已经全部通过,我用了一个arrList存储每一个验证的结果,最后遍历这个函数。
this.valiCount = 0;
this.arrVali = {
newName : false,
newPassword : false,
newPassword2: false,
newEmail : false,
newTel : false
};- 点击验证的时候,
validate()
遍历arrVali中的每一个键的值,计算true的个数统计是否通过验证。在每个input验证的时候都用vali()
方法,改变他们对应的键的值。vali : function(key,setValue) {this.arrVali[key] = setValue;},
-
-
然后这样知识基础流程,还有几个关键点。
- 如果用户什么操作都不做,直接点击提交,按照我本来的思路,要么只有再点击提交的时候调用所有的方法,但是我觉得并不可取,所以我就单独作了处理。
<p class="tips">必填,请填写11位手机号</p>
改成这样,预先填充内容,这样只需要点击提交的时候,让.tips
显示出来就可以了。var submitBtn = 0;
用一个变量,标记是否没有操作过表单,在每次操作表单后就改变submitBtn = 1
,再点击的时候在判断submitBtn的值就可以了。 - 密码输入框和确认密码输入框都需要进行是否为空,是否满足格式输入,然后确认密码框需要添加一个是否和密码输入框一致。如果给每一个按钮绑定不同的方法:
- 首先,这样并不是一个简单的有条理的写法
- 其次,无法做到(或者会很复杂)输入密码框改变的时候实时验证确认密码框。
- 所以,拆分成两个方法,第一个
passwordVali ()
负责验证输入格式和是否为空,passwordCom()
验证是否满足两次输入一致。当然,其实也不是流程就这样就可以了,我还是经过了很多次尝试,最后结果是这样的:- 确认密码
passwordCom()
先判断是否和输入框1的内容一致,如果一致调用passwordVali ()
再调用判断格式方法,如果不一致就显示“两次输入不一致”。 - 第一次输入密码,blur事件调用
passwordVali ()
方法,判断格式,然后因为要做到如果改变输入框1实时判断输入框2的值,所以用一个var first = 0
标记是否还未触发过输入框2,如果触发过,改变first = 1
,然后改变输入框1的时候,调用passwordCom()
- 确认密码
- 如果用户什么操作都不做,直接点击提交,按照我本来的思路,要么只有再点击提交的时候调用所有的方法,但是我觉得并不可取,所以我就单独作了处理。
inputPassword.addEventListener('blur', function() {
formObj.passwordVali(1);
if(first){
formObj.passwordCom(2);
}else{
first = 1;
}
});
inputPassword2.addEventListener('blur', function() {
formObj.passwordCom(2);
});
总结
以上就是我的一些思路,我觉得思路还是略微混乱,特别是在两个输入框互相验证的情况下,但是感觉自己还是学到很多,以及这次用到了以前的学到的绑定方法,优化?也不一定,通过父元素代理子元素的事件。继续加油波,为什么markdown不能加表情,O(∩_∩)O哈哈~
要求
示例图所示
- 当选择在校生时,出现两个select下拉菜单,一个选择城市,一个选择学校,当选择非在校生时,出一个文本输入框
- 学校下拉菜单里的学校名单均为城市下拉菜单中所选的城市中的大学,当城市发生变化时,学校一起发生变化
##思考
其实这个的的实现并不难,主要是涉及到对input-radio和select的属性的熟悉。
- 如果要模拟radio样式,我也写过总结,就是:before伪类的运用,
input:checked + label:before
以及选择器的使用,还有label的运用。 - 监听radio的选中事件,还是用了父元素代理。
// 父元素监听点击切换
info.addEventListener('click', function(e) {
var id = e.target.id || e.srcElement.id;
if(id === "stu"){
display(showGroups,uniDiv);
}else if(id === "nstu") {
display(showGroups,comDiv);
}
});
- 然后选择省份后的学校切换,了解几个属性就可以了。
- selectIndex 当前option 的索引值
- change事件,当select改变时触发
var preIndex = 0;
province.addEventListener('change', function() {
var index = province.selectedIndex;
var list = universitys[index];
if(index === preIndex) {
return;
}else {
university.innerHTML = '';
for(var i = 0; i < list.length; i++) {
var option = document.createElement('option');
option.innerHTML = list[i];
university.appendChild(option);
}
}
});