技术总结:#
一 事件委托
事件委托利用冒泡的原理,把事件加到父级身上,触发执行效果,其好处:a 提高性能,新添加的元素,还有之前的事件
实现功能:动态添加input,每个input标签
html代码
已添加事项
数量
预算(元)
操作
js代码
拓展 ↓↓↓
1 事件:在浏览器客户端应用平台,基本都是以事件驱动的,即某个事件发生,然后做出相应的动作。浏览器的事件表示的某些事情发生的信号,下面是比较常用的事件:
2冒泡原理:
想象一下,气泡从水底开始往上升,由深到浅,升到最上面。在上升的过程中,气泡会经过不同深度层次的水。这个气泡就相当于事件,而水则相当于我们的整个DOM树;事件从DOM树的底层层往上传递,直到传递到DOM的根节点
我们现在想实现这样的功能,在div1点击的时候,弹出“我是最外层div”,点击span时,弹出“我是span”——》终止事件冒泡
方法一:在相应的处理函数内,加入event.stopPropagation(),终止事件的广播分发,这样事件停留在本节点,不会再往外传播
方法二:元素收到事件后,判断是否符合要求,然后做相应的处理,然后事件继续冒泡往上传递,进一步的,我们把本来每个元素都要有的处理函数,都交给了其祖父节点body 元素来完成了,也就是说,span,div2,div1 将自己的响应逻辑委托给body,让它来完成相应逻辑,自己不实现相应逻辑,这个模式,就是所谓的事件委托。
二 信息验证,普通验证和异步请求验证。模仿插件自己写的插件,目前测试没有问题,注释很明确且详细,贴上代码
插件
var ex = {
/*
{
form : document.getElementById(""), // 表单DOM
submit : document.getElementById(""), // 提交按钮,可选(若有项目验证失败,则禁用按钮阻止提交)
rules : {
email : funtion(val, result){
if(xxx)
return result(false); // 验证失败
else
return result(true); // 验证成功
},
ajaxUser: function (val, result){ // result 为结果回调函数,需将验证结果传入 true/false
ex.ajax({
url : "http://temp.com/", // ajax请求地址
success : function(data){ // ajax 请求成功的回调函数
return result(data.status == 200);
},
error : function(e){ // ajax 请求失败的回调函数
console.log(e.message)
},
data : "user=jill", // 发送的数据
type : "get", // 请求方式:get/post
dataType : "json" // 服务端返回数据类型
});
}
},
msg : { // 错误提示信息
user : { // 绑定控件 使用 data-warn 属性
email : "无效用户名", // 对应验证规则
noempty : "用户名不能为空"
}
},
able : function (result){ // 根据整体验证结果执行, 可选(用于做DOM操作阻止提交表单)
},
failed : function (back){ // 验证控件failed执行方式
back.val ;
back.msg ;
back.ele ;
},
final : function (){ // 提交表单动作
ex.ajax({
url : "http://120.25.66.55/ivan/checkParams.php", // ajax请求地址
data : "user=jill&passwd=123456", // 发送的数据
type : "get", // 请求方式:get/post
dataType : "json", // 服务端返回数据类型
success : function(data){ // ajax 请求成功的回调函数
switch (data.statusCode) {
case 200:
alert("登录成功");
location = "somewhere";
break;
case 201:
alert("密码或用户名错误");
default:
break;
}
},
error : function(e){ // ajax 请求失败的回调函数
console.log(e.message);
}
});
}
}
*/
verify: function (obj) {
if (undefined == obj.form) obj.form = document.forms[0];
if (undefined == obj.submit) obj.form = document.forms[0];
if (undefined == obj.rule) obj.rule = {};
if (undefined == obj.msgs) obj.msgs = {};
// 全局规则
var g_rule = {
v_noempty: function (val, fn) {
return fn(val != "");
},
v_number: function (val) {
return fn(!isNaN(val));
}
}
var stopEvent = function (ev) {
ev.preventDefault && ev.preventDefault();
ev.stopPropagation && ev.stopPropagation();
ev.cancelBubble = true;
return false;
};
var failed = function (ele, rule) {
var msg = "";
if (undefined != ele.dataset.warn) msg = obj.msgs[ele.dataset.warn][rule];
if (undefined != obj.failed) obj.failed({
"val": ele.value,
"msg": msg,
"ele": ele
});
};
var main = function (ev, ele, fn) {
var className = ele.className;
for (key in obj.rules) {
g_rule[key] = obj.rules[key];
}
for (key in g_rule) {
if (!ex.classop.find(className, key)) continue;
if (!g_rule[key](ele.value, function (result) {
if (undefined == obj.able) obj.able(result);
if (result) {
for (var i = 0; i < verifyList.length; i++) {
if (verifyList[i]) continue;
if (undefined != obj.submit) document.getElementById(obj.submit).disabled = true;
return false;
}
if (undefined != obj.submit) document.getElementById(obj.submit).disabled = false;
return true;
} else {
failed(ele, key);
if (undefined == ele.exid) ele.exid = verifyList.length;
verifyList[ele.exid] = false;
if (undefined != obj.submit) document.getElementById(obj.submit).disabled = false;
return false;
}
})) return false;
}
if (undefined == obj.rules) return true;
return true;
};
var vForm = function (form) {
for (key in obj.rules) {
g_rule[key] = obj.rules[key];
}
for (key in g_rule) {
var eles = document.getElementsByClassName(key);
for (var i = 0; i < eles.length; i++) {
var ele = eles[i];
if (!g_rule[key](eles[i].value, function (result) {
if (undefined == obj.able) obj.able(result);
if (result) {
for (var i = 0; i < verifyList.length; i++) {
if (verifyList[i]) continue;
if (undefined != obj.submit) document.getElementById(obj.submit).disabled = true;
return false;
}
if (undefined != obj.submit) document.getElementById(obj.submit).disabled = false;
return true;
} else {
failed(ele, key);
if (undefined == ele.exid) ele.exid = verifyList.length;
verifyList[ele.exid] = false;
if (undefined != obj.submit) document.getElementById(obj.submit).disabled = false;
return false;
}
})) return false;
}
}
return true;
}
var verifyList = {};
document.addEventListener('DOMContentLoaded', function () {
document.removeEventListener('DOMContentLoaded', arguments.callee, false);
var changeListen = function (ev) {
ev = ev || window.event;
var target = ev.target || ev.srcElement;
main(ev, target);
};
document.getElementById(obj.form).addEventListener('change', changeListen, false);
//document.getElementById(obj.form).addEventListener('click', changeListen, false);
document.getElementById(obj.form).addEventListener('input', changeListen, false);
document.getElementById(obj.form).addEventListener('propertychange', changeListen, false);
document.getElementById(obj.form).addEventListener('submit', function (ev) {
ev = ev || window.event;
var target = ev.target || ev.srcElement;
var result = vForm(document.getElementById(obj.form));
if (!result || (undefined != obj.final && !obj.final(ev, target)))
return stopEvent(ev);
}, false);
}, false);
},
/*
ajax({
url : "http://~", // ajax请求地址
success : function(data){ // ajax 请求成功的回调函数
// do something
},
error : function(e){ // ajax 请求失败的回调函数
},
data : "id=3", // 发送的数据
type : "get" // 请求方式:get/post
dataType : "json" // 服务端返回数据类型
})
*/
ajax: function (obj) {
if (undefined == obj.url) throw ("ajax url was undefined.");
if (undefined == obj.success) obj.success = function (d) {
};
if (undefined == obj.error) obj.error = function (d) {
};
if (undefined == obj.data) obj.data = "";
if (undefined == obj.type) obj.type = "get";
if (undefined == obj.dataType) obj.dataType = "text";
try {
var oReq = new XMLHttpRequest();
oReq.onload = function (e) {
obj.success(e.target.response);
};
var url = obj.url +
obj.url.indexOf("?") < 0 ? "?" : "&" + "___rand=" + Math.random();
if ("get" == obj.type.toLowerCase()) url = url + "&" + obj.data;
oReq.open(obj.type, obj.url, true);
//判断请求方式是get/post,若是get请求方式,直接发送,若是post请求,则添加xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
oReq.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
oReq.send(obj.data);
oReq.responseType = obj.dataType;
if ("get" == obj.type.toLowerCase()) oReq.send();
else oReq.send(obj.data);
} catch (e) {
obj.error(e);
}
},
classop: {
// 移除class
remove: function (className, removeName) {
className = className.Trim().replace(removeName, "");
className = className.replace(" ", "").Trim();
return className;
},
// 添加class
add: function (className, addName) {
className = className.Trim() + " " + addName.Trim();
className = className.replace(" ", " ").Trim();
return className;
},
// 查找class
find: function (className, findName) {
if (!className || "" == className) return false;
var classList = className.Trim().split(" ");
for (var i = 0; i < classList.length; i++) {
if (classList[i] == findName.Trim()) {
return true;
}
}
return false;
}
}
}
/* ---------------------------------------------------------------
* 重載JS中String.prototype函數功能
* 功能:去掉字符串(左|右)指定字符,若不传参,则去掉空白符
* 示例:var str = " 123 ";
* str = str.Trim(); // "123"
* -------------------------------------------------------------- */
String.prototype.Trim = function (str) {
return this.replace((new RegExp("(^(" + (str || "\\s") + ")*)|((" + (str || "\\s") + ")*$)", "g")), '');
}
String.prototype.LTrim = function (str) {
return this.replace((new RegExp("(^(" + (str || "\\s") + ")*)", "g")), '');
}
String.prototype.RTrim = function (str) {
return this.replace((new RegExp("((" + (str || "\\s") + ")*$)", "g")), '');
}
引入此插件,下面分别贴上关键代码 普通验证和异步验证
HTML里几个参数要对应噢
1 form表单的id
2 input 标签 需加入,a绑定控件 使用 data-warn
属性;
b绑定错误信息 ,使用class
属性
其中,id
,name
不做要求,留给后台
拿下面异步请求的html代码作为例子:
普通验证
异步验证
//引入插件